Paperclip宝石触发CSRF令牌验证问题

11

我有一个使用了paperclip gem (v 3.4.0) 的Rails 3.1应用程序。简而言之,我有一个故事模型和一个帖子模型。一个故事可以有多个帖子。

#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

作为您可以看到的,帖子可能会有照片附件。我使用paperclip来管理这些附件。
我使用JavaScript / jQuery在客户端动态生成提交这些帖子的表单。我的问题是...如果帖子不包括照片附件,一切都正常。但是,如果帖子有照片附件,我会收到以下错误消息,并且帖子无法发布:
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

作为结果,我的会话数据被销毁了,我甚至无法通过Firebug查看请求头。Put请求在Firebug中根本没有出现。
现在,毫不意外的是,我可以通过在PostController中使用以下方法来解决这个问题:
skip_before_filter :verify_authenticity_token, :only => [:create]

但我不想放弃这种安全性。我也尝试通过js/jquery向我的表单添加CSRF头:

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

但这并没有解决问题,正如我上面所说,我甚至无法看到请求头数据以查看头信息。有人能想出纸夹触发问题的原因吗?
3个回答

1
我知道离我最初发帖的时间已经有一段时间了,但人们仍在通过搜索找到它,所以我想更新一下答案。上述问题与Paperclip无关。提交表单时没有使用csrf令牌,因为我正在使用remotipart.js来处理具有文件附件的表单的提交。Remotipart通过将表单数据复制到i-frame中,启用类似于ajax的表单提交,然后进行正常(非ajax)提交,同时您的站点保持活动状态。有关通过i-frame进行ajax文件上传的更详细说明,请参见本文。在先前的remotipart版本中,没有将csrf令牌复制到由i-frame提交的表单中。支持remotipart的好人现在已经修复了这个缺陷。您可以在此处找到修复方法。

0

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

在 JavaScript 中

以及在布局中

<%= csrf_meta_tags %>

文件应该足以使其正常工作。 否则,您可以使用处理CSRF令牌的jquery-rails gem。

大多数情况下,您只需要在布局中使用<%= csrf_meta_tags %> - 在<head>部分。 - Eskim0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接