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

查看:91
本文介绍了GET请求(无JSON)无法使用Rails 4.1上的Devise 3.2.4验证CSRF令牌的真实性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



我的应用程序布局包括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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆