【发布时间】:2014-07-05 13:25:21
【问题描述】:
突然之间,我无法再登录 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 例外。
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'
我目前正在通过this similar question 的建议进行故障排除,但到目前为止还没有运气。考虑尝试“protect_from_forgery except::sign_in”,但如果我能找出根本原因,这似乎是一个不必要的妥协。
【问题讨论】:
-
我在开发环境的一个会话期间查看了多个页面的页面源,并且身份验证令牌始终相同。在生产中,这些页面之间是不同的,我猜这是触发无法验证 CSRF 令牌真实性的原因。
-
我已经测试了在 heroku 中运行 1 个 dyno 与超过 1 个。一旦我增加到超过 1 个 dyno,我就会开始遇到问题。当进程从 web 1 切换到 web 2 时,将为用户重新创建真实性令牌,然后不再匹配,从而生成错误。似乎没有人能告诉我为什么……或者更可能是我不知道如何正确地问这个问题。
标签: ruby-on-rails heroku devise csrf