Rails uploadify 和 Rails 交互问题

scott · 2012年03月02日 · 最后由 sg552sg552 回复于 2013年03月17日 · 6545 次阅读

大家用过 uploadify 上传文件吗?有没有到报错的情况? WARNING: Can't verify CSRF token authenticity. 但是要是刷新几次就好了,不是从能出现,不知道是那里出问题,求帮助。

ps:已经加了 middleware 等。

flash_session_cookie_middleware.rb

require 'rack/utils'
 class FlashSessionCookieMiddleware
  def initialize(app, session_key = '_session_id')
    @app = app
    @session_key = session_key
  end

  def call(env)
    if env['HTTP_USER_AGENT'] =~ /^(Adobe|Shockwave) Flash/
      req = Rack::Request.new(env)
      env['HTTP_COOKIE'] = [ @session_key,
                             req.params[@session_key] ].join('=').freeze unless req.params[@session_key].nil?
      env['HTTP_ACCEPT'] = "#{req.params['_http_accept']}".freeze unless req.params['_http_accept'].nil?
    end

    @app.call(env)
  end
end

session_stroe.rb

Rails.application.config.middleware.insert_before(
  ActionDispatch::Session::CookieStore,
  FlashSessionCookieMiddleware,
  Rails.application.config.session_options[:key]
)

application.rb

%w(middleware).each do |dir|
   config.autoload_paths << "#{Rails.root.to_s}/app/#{dir}"
end

提交的数据里要有 token 'authenticity_token': encodeURIComponent($('#uploads').attr("data-form-authenticity-token"))

@ywencn 还是不行啊。

log: Processing by DataController#parse_csv as JSON Parameters: {"Filename"=>"gdp.csv", "_http_accept"=>"application/javascript", "folder"=>"/data/", "fileext"=>"*.csv;", "authenticity_token"=>"undefined", "_dituhui_session"=>"BAh7CkkiGXdhcmRlbi51c2VyLnVzZXIua2V5BjoGRVRbCEkiCVVzZXIGOwBGWwZpCUkiIiQyYSQxMCRyc3dRVlI2Vk1uSkRSSkFycmN2YXdlBjsAVEkiHXdhcmRlbi51c2VyLnVzZXIuc2Vzc2lvbgY7AFR7BkkiFGxhc3RfcmVxdWVzdF9hdAY7AEZJdToJVGltZQ1CCBzAUmRAVgk6C0Bfem9uZUkiCFVUQwY7AFQ6DW5hbm9fbnVtaQKiAjoNbmFub19kZW5pBjoNc3VibWljcm8iB2dASSIKZmxhc2gGOwBGbzolQWN0aW9uRGlzcGF0Y2g6OkZsYXNoOjpGbGFzaEhhc2gJOgpAdXNlZG86CFNldAY6CkBoYXNoewY6C25vdGljZVQ6DEBjbG9zZWRGOg1AZmxhc2hlc3sGOw9JIj50cmFuc2xhdGlvbiBtaXNzaW5nOiB6aC1DTi5kZXZpc2Uuc2Vzc2lvbnMudXNlci5zaWduZWRfaW4GOwBGOglAbm93MEkiD3Nlc3Npb25faWQGOwBGSSIlMGU2ZjViYTYyNjI2MmUwYjBlMTNjM2E3ZGZiNzM1MjgGOwBUSSIQX2NzcmZfdG9rZW4GOwBGSSIxUFBkbnZHM3A4WXpKWDlaNjMxOXFDaXhRZmxhdVdKRUw3Vm43bDBhRWl1Zz0GOwBG--2fab5f7ebe958ce6fbbd46de38a88660a51d54e1", "Filedata"=>#>, "Upload"=>"Submit Query"} WARNING: Can't verify CSRF token authenticity

#2 楼 @scott 我只是举个例子。。要这么带上,不是让你直接贴。。 你可以参考实际例子 https://github.com/websymphony/Rails3-Paperclip-Uploadify https://github.com/davesouth/mongoid-carrierwave-uploadify

这个问题是由于 Flash 的请求,Rails 无法获取 Session ,也就无法得到 CSRF ,也就是说连 current_user 也是无法获取到的,网上有很多教程是用 FlashSessionCookieMiddleware 这个方式来做,但实际用起来却没有那么稳定。 解决办法其实简单点可以关掉 verify_authenticity_token,然后用自定义加密的 current_user.id 方式代替,提交的时候将加密过的 current_user.id 提交回来解密就能得到当前用户的编号了。

class AttachmentsController < ApplicationController
  skip_before_filter :verify_authenticity_token, :only => [:create]

  def new
    @user_id = AES.encrypt(current_user.id.to_s, "自定义密钥")
  end

  def create
    @user_id = AES.decrypt(params[:uid], "自定义密钥")
    @attachment = Attachment.new(params[:attachment])
    @attachment.user_id = @user_id
    @attachment.save
  end
end 

@ywencn 谢谢,我之前就是按https://github.com/websymphony/Rails3-Paperclip-Uploadify 这个做的,就像是@huacnlee 说的,貌似没那么稳定,有时候不行,刷新几次之后就行啦。谢谢两位。我在研究一下关掉 verify_authenticity_token 的这个方法吧。

就是 verify_authenticity_token 的问题,之前我也遇到过。

mark 一下,搞了很久也是这个问题

不稳定的话可以用下面方法解决,就是把 session 加载进来

prepend_before_filter :load_session, only: :flash_upload

def load_session
   unless session.loaded?
     se = Marshal.load(ActiveSupport::Base64.decode64(params["_dituhui_session"]))
     logger.info("\n--------session is: #{se.inspect}-----------\n")
     request.session.update(se)
   end
 end

其实就是在 authenticate_user! 前,执行 load_session

protect_from_forgery

(不想挖坟的。。。)

uploadify 的 session 问题,本质上就是 swf 的问题。对 RAILS3 的解决方案和 rails2.3 的,看这里: http://stackoverflow.com/questions/5366253/uploadify-flash-sessions-and-rails-2-3-8/15456801#15456801

对不起,更正,我说错了。。。还是需要设置 authentication token 的。在文件上传上我花了一天半的时间。。。session 问题弄了 6 个小时。(净时间) 。经验见: http://www.siwei.me/blog/posts/uploadify-in-rails

需要 登录 后方可回复, 如果你还没有账号请 注册新账号