GET请求(无JSON)无法使用Rails 4.1上的Devise 3.2.4validationCSRF令牌的真实性

突然间,我无法再登录到heroku上的应用程序生产环境。 或者,如果我进入,只要我点击一个新链接,我就会被重定向到登录屏幕,如果我再次尝试登录,我会看到错误。

日志如下(这是登录时的情况,重定向回登录然后再次登录)。

我的应用程序布局包括CSRF_meta_tags

!!! %html %head %title= full_title(yield(:title)) = include_gon(:init => true) = stylesheet_link_tag "application", media: "all" = javascript_include_tag "application" = csrf_meta_tags = render 'layouts/shim' %meta{content: "width=device-width, initial-scale=1.0", name: "viewport"}/ %body.container-fluid #wrapper = render 'layouts/navigation' = render partial: "shared/flash_messages", flash: flash #content = yield = render 'layouts/footer' %br - if request.env['HTTP_USER_AGENT'].downcase.match(/android|iphone|ipad/) - else = debug(params) if Rails.env.development? = debug(@current_user) if Rails.env.development? 

我的应用程序控制器是protect_from_forgery,但有exception。

 class ApplicationController < ActionController::Base # Prevent CSRF attacks by raising an exception. # For APIs, you may want to use :null_session instead. protect_from_forgery with: :exception before_action :authenticate_user! end 

我已经在我的路线文件中为用户设计了。

  devise_for :users, :skip => [:registrations] as :user do get 'users/edit' => 'devise/registrations#edit', :as => 'edit_user_registration' put 'users/:id' => 'devise/registrations#update', :as => 'user_registration' end 

日志文件在这里供参考。

 Started GET "/users/sign_in" for 58.7.233.232 at 2014-05-16 23:52:48 +0000 Processing by Devise::SessionsController#new as HTML 2014-05-16T23:52:48.995008+00:00 heroku[router]: at=info method=GET path=/assets/application-7d1b02fae40091844b4f616c7ec89e83.js host=slapp.herokuapp.com request_id=8f86c336-0bf2-4419-a07d-0c7ecf79cfb4 fwd="58.7.233.232" dyno=web.2 connect=1ms service=2ms status=304 bytes=249 Rendered layouts/_shim.html.haml (0.3ms) Rendered devise/sessions/new.html.haml within layouts/application (7.9ms) Rendered layouts/_navigation.html.haml (1.2ms) Rendered shared/_flash_messages.html.haml (0.4ms) Rendered layouts/_footer.html.haml (0.4ms) Completed 200 OK in 18ms (Views: 14.1ms | ActiveRecord: 0.0ms) 2014-05-16T23:52:54.997215+00:00 heroku[router]: at=info method=POST path=/users/sign_in host=slapp.herokuapp.com request_id=6fd107af-4a46-4315-843c-6bbf46827df0 fwd="58.7.233.232" dyno=web.1 connect=7ms service=41ms status=422 bytes=1729 Started POST "/users/sign_in" for 58.7.233.232 at 2014-05-16 23:52:54 +0000 vendor/bundle/ruby/2.0.0/gems/devise-3.2.4/lib/devise/controllers/helpers.rb:182:in `handle_unverified_request' Processing by Devise::SessionsController#create as HTML Parameters: {"utf8"=>"✓", "authenticity_token"=>"o5NFnMmQQGcmNxPhzvFYOF+ThrcO1cY1VdZozvQmtOI=", "user"=>{"email"=>"admin@domain.com", "password"=>"[FILTERED]"}, "commit"=>"Login"} Completed 422 Unprocessable Entity in 9ms vendor/bundle/ruby/2.0.0/gems/activesupport-4.1.0/lib/active_support/callbacks.rb:160:in `block in halting' vendor/bundle/ruby/2.0.0/gems/actionpack-4.1.0/lib/action_controller/metal/request_forgery_protection.rb:197:in `verify_authenticity_token' vendor/bundle/ruby/2.0.0/gems/activesupport-4.1.0/lib/active_support/callbacks.rb:166:in `call' Can't verify CSRF token authenticity ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken): vendor/bundle/ruby/2.0.0/gems/actionpack-4.1.0/lib/action_controller/metal/request_forgery_protection.rb:176:in `handle_unverified_request' vendor/bundle/ruby/2.0.0/gems/actionpack-4.1.0/lib/action_controller/metal/request_forgery_protection.rb:202:in `handle_unverified_request' 

我目前正在针对这个类似的问题提出建议,但到目前为止还没有运气。 考虑尝试“protect_from_forgery除了:: sign_in”,但如果我能找出根本原因,这似乎是一种不必要的妥协。

我认为csrf令牌是在一个dyno中生成的,而下一个http请求正在击中第二个dyno,因此csrf令牌不匹配。 csrf令牌需要保存到数据库,因此两个dynos都可以共享它。 尝试在提供页面和处理表单时写出$ DYNO。 这将显示哪个dyno正在处理csrf令牌以及它是相同的dyno还是不同的dyno。

Interesting Posts