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

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

问题描述

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

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).

我的应用程序布局包括 CSRF_meta_tags

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?

我的应用程序控制器是protect_from_forgery 例外.

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'

我目前正在通过关于 这个类似的问题 但到目前为止还没有运气.考虑尝试protect_from_forgery except::sign_in",但如果我能找出根本原因,这似乎是一种不必要的妥协.

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.

推荐答案

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

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天全站免登陆