2013-03-07 10 views
11

Ich habe eine Rails 3.1-App, die den Büroklammer-Edelstein (v 3.4.0) verwendet. In einer Nussschale. Ich habe ein Story-Modell und ein Post-Modell. Eine Geschichte kann viele Beiträge haben.Paperclip-Material, das CSRF-Token-Verifizierungsprobleme auslöst

#story.rb 

class Story < ActiveRecord::Base 

    attr_accessible :title, :user_id, :username, :posts_attributes 

    belongs_to :user 
    has_many  :posts, :dependent => :destroy, 
         :order => "created_at DESC" 

    accepts_nested_attributes_for :posts, :reject_if => lambda { |t| t['contents'].nil? } 

end 

#post.rb 

class Post < ActiveRecord::Base 

    attr_accessible :contents, :photo, :dimensions 

    belongs_to :story, :touch => true 
    belongs_to :user, :touch => true 

    has_attached_file :photo, 
        :styles => { 
         :medium => { :geometry => "400x400>" }, 
         :thumb => { :geometry => "100x100>" }, 
        }, 
        :processors => [:thumbnail], 
        :storage => :s3, 
        :s3_credentials => "#{Rails.root.to_s}/config/s3.yml", 
        :path => "/:style/:id/:filename" 


    before_save :extract_dimensions 

    serialize :dimensions 

    validates :contents, :presence => true, 
         :length   => { :maximum => 399, 
             :minimum => 5 } 
    validates :user_id, :presence => true 

    validates_attachment_content_type :photo, 
    :content_type => ['image/jpeg', 'image/png', 'image/gif', 'image/jpg'], 
    :message => "Sorry, we don't support that type of image format" 

end 

Wie Sie sehen können, können Beiträge ein Foto Befestigung haben. Ich verwende Büroklammer, um diese Anhänge zu verwalten.

Ich generiere das Formular, das diese Posts dynamisch auf dem Client mit Javascript/jquery postt. Mein Problem ist das. . . Wenn der Beitrag keinen Foto-Anhang enthält, funktioniert alles perfekt. Wenn jedoch ein Post ein Foto Anlage hat, erhalte ich folgende Fehlermeldung und die Post nicht POST:

WARNING: Can't verify CSRF token authenticity 
    User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = 61 LIMIT 1 
    (0.3ms) BEGIN 
    (0.2ms) COMMIT 
Completed 401 Unauthorized in 238ms 

Als Ergebnis werden meine Session-Daten zerstört, und ich kann das nicht einmal sehen, Anfrage Header mit Firebug. Die Put-Anfrage erscheint einfach nicht im Firebug.

Nun, nicht überraschend, ich kann mit dem folgend in dem Postcontroller, um dieses Problem umgehen:

skip_before_filter :verify_authenticity_token, :only => [:create] 

Aber ich will nicht diese Sicherheit verzichten. Ich habe auch versucht, den CSRF-Header zu meiner Form Zugabe über js/jquery:

jQuery.ajaxSetup({ 
    beforeSend: function(xhr) { 
    xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-   
      token"]').attr('content')); 
    } 
}); 

Aber das löst nicht das Problem, und wie ich oben gesagt, kann ich nicht einmal die Anforderungskopfdaten sehen, um zu sehen die Überschrift.

Kann jemand mit einem Grund warum Papierklammer löst das Problem?

+4

Das gleiche Problem hier – Pasta

Antwort

1

Ich weiß, dass es schon eine Weile her, seit ich zum ersten Mal die obige Frage gestellt, aber Menschen finden es immer noch in ihren Recherchen, so dachte ich, ich aktualisieren würde Dinge mit einer Antwort.

Das Problem, das ich oben besprochen habe, hatte nichts mit Paperclip zu tun. Das Formular wird ohne ein csrf-Token übergeben, da ich remotiart.js verwende, um die Übermittlung von Formularen mit Dateianhängen zu verarbeiten. Remotiart ermöglicht eine Ajax-ähnliche Übermittlung eines Formulars, indem die Formulardaten in einen I-Frame kopiert werden, der dann eine normale (d. H. Nicht-Ajax-) Eingabe vornimmt, während Ihre Site aktiv bleibt. Eine genauere Beschreibung der Ajax-Datei-Uploads über i-frame finden Sie unter this article.

In früheren Versionen von Remotipart wurde das csrf-Token nicht in das Formular kopiert, das vom i-frame übergeben wird. Die guten Leute, die remotiparts unterstützen, haben nun dieses Manko behoben.Sie können das Update finden here

0
$.ajaxSetup({ 
    beforeSend: function(xhr) { 
     xhr.setRequestHeader('X-CSRF-Token', 
          $('meta[name="csrf-token"]').attr('content')); 
    } 
}); 

in js

und im Layout

<%= csrf_meta_tags %> 

Datei sollte es genug sein, Arbeit zu machen.

sonst kann man jquery-rails gem verwenden, die CSRF-Token

Griffe
+0

meistens brauchen Sie nur <% = csrf_meta_tags%> in Ihr Layout - im Abschnitt . – Eskim0