GET请求(无JSON)无法使用Rails 4.1上的Devise 3.2.4验证CSRF令牌的真实性 [英] GET request (no JSON) Can't verify CSRF token authenticity with Devise 3.2.4 on Rails 4.1
问题描述
日志如下(这是登录的情况,重定向回登录,然后再次登录)。
我的应用程序布局包括CSRF_meta_tags
!!!
%html
%head
%title = full_title(yield(:title))
= include_gon(:init => true)
= stylesheet_link_tagapplication媒体:all
= javascript_include_tagapplication
= csrf_meta_tags
= render'layouts / shim'
%meta {content:width = device-width, 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
- 如果request.env ['HTTP_USER_AGENT']。 downcase.match(/ android | iphone | ipad /)
- else
= debug(params)如果Rails.env.development?
= debug(@current_user)如果Rails.env.development?
,我的应用程序控制器是protect_from_forgery与异常。
class ApplicationController< ActionController :: Base
#通过引发异常来防止CSRF攻击。
#对于API,您可能需要使用:null_session。
protect_from_forgery with::exception
before_action:authenticate_user!
end
我在我的路由文件中设置了用户。 / p>
devise_for:users,:skip => [:registration]
as:user do
get'users / edit'=> 'devise / registrations#edit',:as => 'edit_user_registration'
put'users /:id'=> 'devise / registrations#update',:as => 'user_registration'
end
日志文件在这里供参考。
开始GET/ users / sign_in为58.7.233.232在2014-05-16 23:52:48 +0000
加工处理:: 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.232dyno = web.2 connect = 1ms service = 2ms status = 304 bytes = 249
渲染布局/ _shim.html.haml 0.3ms)
在布局/应用程序(7.9ms)内渲染的设计/会话/ new.html.haml
渲染布局/ _navigation.html.haml(1.2ms)
渲染共享/ _flash_messages。 html.haml(0.4ms)
渲染布局/ _footer.html.haml(0.4ms)
在18ms内完成200 OK(视图:14.1ms | ActiveRecord:0.0ms)
2014-05-16T23:52:54.997215 + 00:00 heroku [router]:at = info method = POST path = / users / sig n_in host = slapp.herokuapp.com request_id = 6fd107af-4a46-4315-843c-6bbf46827df0 fwd =58.7.233.232dyno = web.1 connect = 7ms service = 41ms status = 422 bytes = 1729
在2014-05-16 23:52:54启动POST/ users / sign_in为58.7.233.232 +0000
vendor / bundle / ruby / 2.0.0 / gems / devise-3.2.4 / lib / devise / controllers / helpers.rb:182:在`handle_unverified_request'
处理由Devise :: SessionsController#创建为HTML
参数:{utf8=>✓, authenticity_token=>o5NFnMmQQGcmNxPhzvFYOF + ThrcO1cY1VdZozvQmtOI =,user=> {email=>admin@domain.com,password=>[FILTERED]},commit= >登录}
已完成422 9ms中的无法处理的实体
vendor / bundle / ruby / 2.0.0 / gems / activesupport-4.1.0 / lib / active_support / callbacks.rb:160:在'block in halting'
vendor / bundle / ruby / 2.0.0 / gems / actionpack-4.1.0 / lib / action_controller / metal / request_forgery_protection.rb:197:在`verify_authenticity_token'
vendor / bundle / ruby / 2.0.0 / gems / activesupport-4.1.0 / lib / active_support / callbacks.rb:166:在`call'
无法验证CSRF令牌真实性
ActionController :: InvalidAuthenticityToken(ActionController :: InvalidAuthenticityToken )
vendor / bundle / ruby / 2.0.0 / gems / actionpack-4.1.0 / lib / action_controller / metal / request_forgery_protection.rb:176:在`handle_unverified_request'
供应商/ bundle / ruby / 2.0.0 / gems / actionpack-4.1.0 / lib / action_controller / metal / request_forgery_protection.rb:202:在`handle_unverified_request'
我目前正在排查有关这个相似的问题,但是迄今没有运气。考虑到尝试protect_from_forgery除了:sign_in,但如果我能找出根本原因,似乎是一个不必要的妥协。
我认为csrf令牌正在一个dyno生成,下一个http请求正在击中第二个dyno,所以csrf令牌不匹配。
csrf令牌需要保存到数据库,因此可以由两个dynos共享。
尝试写入$ DYNO当页面被提供和表单被处理。这将显示哪个动力处理csrf令牌,以及它是否是同一个dyno或另一个。
All I a sudden I can no longer login to my app production environment on heroku. Or, if I do get in, as soon as I click a new link I get redirected to the login screen where I start seeing errors if I try and login again.
The logs are as follows (this was in the case of login, redirect back to login and then login again).
My applications layout includes 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?
and my application controller is protect_from_forgery with 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
and I have devise for user in my routes file.
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
log files are here for reference.
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'
I am currently troubleshooting with suggestions on this similar question but no luck so far. Considering trying the "protect_from_forgery except: :sign_in" but it seems like an unnecessary compromise if I can find out the root cause.
I think the csrf token is being generated in one dyno and the next http request is hitting the second dyno, so the csrf token doesn't match. The csrf token needs saving to a database so it can be shared by both dynos. Try writing out $DYNO when the page is served and when the form is processed. This will show you which dyno is processing the csrf token and whether it is the same dyno or a different one.
这篇关于GET请求(无JSON)无法使用Rails 4.1上的Devise 3.2.4验证CSRF令牌的真实性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!