【问题标题】:Invalid authenticity token in RailsRails 中的真实性令牌无效
【发布时间】:2018-06-29 04:51:18
【问题描述】:

尝试使用 Devise 登录用户,我收到无效的真实性令牌错误。

我的布局中有csrf_meta_tags,请求参数中有authenticity_token。正如其他问题的答案所建议的那样,protect_from_forgery with: :exceptionbefore_action :authenticate_user! 之前。

如果我注释掉 protect_from_forgery,我会在我的服务器日志中看到以下内容:

Started POST "/users/sign_in" for 127.0.0.1 at 2018-01-19 16:13:46 -0500
Processing by Devise::SessionsController#create as HTML
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"[TOKEN]", "user"=>{"badge_number"=>"0285", "password"=>"[FILTERED]"}, "commit"=>"Log in"}
    User Load (0.3ms)  SELECT  `users`.* FROM `users` WHERE `users`.`badge_number` = '0285' ORDER BY `users`.`id` ASC LIMIT 1
     (0.2ms)  SELECT `divisions`.`id` FROM `divisions` INNER JOIN `divisions_users` ON `divisions`.`id` = `divisions_users`.`division_id` WHERE `divisions_users`.`user_id` = 2
    CACHE  (0.0ms)  SELECT `divisions`.`id` FROM `divisions` INNER JOIN `divisions_users` ON `divisions`.`id` = `divisions_users`.`division_id` WHERE `divisions_users`.`user_id` = 2  [["user_id", 2]]
Redirected to http://localhost:3000/
Completed 302 Found in 141ms (ActiveRecord: 2.1ms)


Started GET "/" for 127.0.0.1 at 2018-01-19 16:13:46 -0500
Processing by IncidentsController#index as HTML
Completed 401 Unauthorized in 0ms (ActiveRecord: 0.0ms)

所以看起来登录正在工作,但是重定向到请求的路径 (/) 会导致 401 并被重定向到登录页面,就好像登录不工作一样。

但是,这一切都不能真正解释为什么我首先会收到真实性令牌错误。

不知道下一步调查该问题可能是什么,因为据我所知,CSRF 令牌验证所需的所有元素都已到位。

【问题讨论】:

  • 您的配置设置正确吗?这篇文章似乎很相关stackoverflow.com/questions/28060089/…
  • 该选项之前不在我的配置中,但添加它并重新启动服务器不会产生任何变化。

标签: ruby-on-rails authentication


【解决方案1】:

我通过清除本地主机的 cookie 来解决此问题。

我曾通过 localhost 端口使用 SSH 隧道来访问生产站点,因此基于冲突会话和 secret_key_base 的 cookie 位于 localhost 域中。

我通过在 cookie 名称前添加 Rails 环境来防止这种情况再次发生:

Rails.application.config.session_store :cookie_store, key: "_incidents_#{Rails.env}_session"

因此,尽管使用 localhost 访问我的开发和生产环境,但由于处于不同的环境中,它们将写入不同的 cookie。

【讨论】:

    【解决方案2】:

    对于 Rails 5,请注意,protect_from_forgery 不再添加到 before_action 链,所以如果你之前设置了 authenticate_user protect_from_forgery,您的请求将导致“无法验证 CSRF 令牌真实性。”[link]

    要解决此问题,请更改调用它们的顺序,或使用:

    protect_from_forgery with: :exception, prepend: true

    【讨论】:

    • 对,我在帖子中提到过。只是为了确认一下,在before_action :authenticate_user 之前直接有protect_from_forgery 就足够了,对吗?这是我的应用程序控制器中的第一行。或者我需要添加prepend: true 除了它是第一个吗?
    • 是的,够了,如果仍然出现错误,请尝试重新启动服务器。还有一个不错的post 关于这个
    • 感谢您的帖子,我现在明白了。不幸的是,由于调用顺序已经正确,这似乎不是问题的根源。
    猜你喜欢
    • 2010-11-15
    • 1970-01-01
    • 2018-06-20
    • 2019-06-20
    • 1970-01-01
    • 1970-01-01
    • 2011-03-04
    • 2013-04-21
    • 2016-03-19
    相关资源
    最近更新 更多