【问题标题】:Rails - Invalid Authenticity Token After DeployRails - 部署后的真实性令牌无效
【发布时间】:2010-11-15 04:08:23
【问题描述】:

我们正在使用 EngineYard Cloud 来部署我们的 Ruby on Rails 应用程序。我们正在运行 Rails v2.3.3。

EngineYard Cloud 以类似于 Capistrano 的方式部署到 AWS 实例。每次部署后,我们都会遇到 Invalid Authenticity Token 错误。具体来说,之前访问过我们的应用程序,然后在部署后访问并尝试提交表单的任何用户都会收到无效的真实性令牌错误。在他们重置网站的 cookie 之前,此错误一直存在。在他们重置 cookie 后,网站按预期运行,没有错误。

我们正在使用 ActiveRecord 的会话存储,并且会话正在保存到数据库中。

这是我们看到的错误:

ActionController::InvalidAuthenticityToken /usr/lib/ruby/gems/1.8/gems/actionpack-2.3.3/lib/action_controller/request_forgery_protection.rb:79:in `verify_authenticity_token'

部署后会话对象为nil,但是会话数据仍然存在数据库中,会话ID cookie仍然存在:

会话:

  • 会话 ID:无
  • 数据:无

我们无法解释这一点。有什么想法可能是根本原因吗?

感谢您的任何建议!


编辑:只是为了更新这一点,我们已经能够隔离一个错误示例。

1) 用户加载表单 2) 代码在服务器上更新 3) 用户提交表单 ** 发生无效的 Authenticity Token 错误

似乎当环境发生变化时,Rails 无法使用真实性令牌来处理。

我们尝试了几个步骤来解决:

  • 重置会话
  • 删除会话 cookie(在 JavaScript 和 Rails 中)
  • 部署代码后擦除数据库中的会话表

没有任何作用。唯一可行的方法是让用户在客户端清除其 cookie。

(我们一直在谷歌搜索(甚至尝试过 Binging!)寻找答案,但没有骰子。这似乎是一个类似的相关问题:http://railsforum.com/viewtopic.php?id=21479

另外:最初我们认为这与我们部署到 EngineYard 是孤立的,但我们也能够在我们通过 Capistrano 部署到的开发服务器上重现它。

我们将不胜感激地接受任何想法。

谢谢!

【问题讨论】:

  • 我现在没有时间查找答案,但是您将想要进入 Rails 源代码并确切了解身份验证令牌是如何生成的。可能是服务器重新启动正在更改用于播种该令牌的值。

标签: ruby-on-rails ruby deployment


【解决方案1】:

回答:经过 EngineYard 的大量工作(他们太棒了!),他们能够诊断出问题。此问题的根本原因是杂种集群的错误。 Mongrel 启动后似乎没有看到第一个 post 请求。 EngineYard 做了大量工作来诊断这一点:

您的代码中似乎没有任何内容导致该问题,我发现我们环境之外的人也遇到了该错误 (http://www.thought-scope.com/2009/07/mongrelcluster-rails-23x-bad-post.html)。我想很多人没有看到它,因为对网站的第一个请求通常不是帖子,或者他们将其归咎于侥幸。

[有一个使用 CURL 的潜在解决方法。] curl 解决方法会对服务器上的每个杂种发出一个简单的 GET 请求,可以这么说。您可以使用 capistrano 执行此操作,但如果您通过仪表板进行部署,这将不起作用。您可以在此处找到有关我们已内置到基础架构中的部署挂钩的简短部分: https://cloud-support.engineyard.com/faqs/overview/getting-started-with-engine-yard-cloud

添加一个简单的运行 curl http://localhost:500x > /dev/null 应该可以工作(其中 x 是您当前设置的 5000-50005 端口)。

我们已通过将堆栈从 Mongrel 切换到Passenger 来解决此问题,但显然,正在对 Mongrel 进行修复。希望这对遇到同样奇怪问题的人有所帮助。

【讨论】:

  • 我刚刚从 Mongrel 切换到了 Passenger,这解决了 3 个拉扯头发的问题。
【解决方案2】:

真实性令牌是表单上的一个隐藏字段,当提交表单时,它会检查以确保发布数据来自实时会话。

这是一种安全措施,可防止恶意人员使用他们网站上的表单提交来对某人的帐户执行删除操作。

您可以通过将其添加到 config/environment.rb 来在整个应用中关闭它

config.action_controller.allow_forgery_protection = false

您可以使用单个控制器将其关闭

skip_before_filter :verify_authenticity_token

或打开它

protect_from_forgery :except => :index

查看ActionController::RequestForgeryProtection::ClassMethods 文档了解更多详情

【讨论】:

  • 感谢您的回复!是的,我们了解令牌的作用以及如何完全禁用它。如果我们能解决它在每次部署时中断的原因,我们希望能够使用它。
  • 这个技巧为这个问题提供了一个很好的解决方法。我在使用 Amazon EC2 时遇到了同样的问题。什么是(安全的)长期解决方案?
  • 这不是解决方案。这是一种不安全的解决方法。
  • 嗨@EricWalker,我遇到了类似的ec2问题,你能分享一下你实施了什么修复吗?
  • @opensource-developer 我在 2010 年或之前的某个时候遇到过这个问题,我不记得我做了什么。正如@rubiii 提到的,关闭伪造保护是不安全的。查看原始问题,加载旧 cookie 时似乎发生了一些不好的事情。所以我想知道更改 cookie 基础是否可以解决它,通过在这里更改 key 值:stackoverflow.com/a/13778235/61048
【解决方案3】:

听起来用于身份验证的密钥在您重新部署时发生了变化,从而使所有现有会话无效。

您是否在任何地方设置了配置参数config.action_controller.session,如果您这样做了,是否有任何东西会在您重新部署时导致它发生变化?

我的一个应用程序在config/environment.rb 中进行了配置,而最近的一个(使用Rails 2.3 生成)将其设置在config/initializers/session_store.rb 中。设置如下:

config.action_controller.session = {
    :secret      => 'long-string-of-hex-digits'
  }

如果由于某种原因您没有进行此配置,rake secret 将为您生成一个密钥,然后可以将其插入到您的配置中。

(如果是——并且它没有被你的部署过程改变——那么我不知道发生了什么。)

【讨论】:

  • 嗯。真是有趣的想法。我当然会更详细地研究这个问题,看看我能找到什么关于密钥是否会在每次部署时发生变化。
【解决方案4】:

如果它只存在于杂种中!我在乘客身上也遇到了完全相同的错误(用户加载表单、部署、提交-> 无效的真实性令牌)。知道您如何通过切换到乘客来解决问题会很有趣?任何进一步的提示都非常受欢迎。我也仔细看看……

干杯!

【讨论】:

  • 好吧,我的错。如weblog.rubyonrails.org/2009/3/16/… 中所述,还应该更新乘客以使用rails 2.3.x(我仍在使用乘客2.0.3)。更新后(原样到 2.2.5)它工作得很好。干杯!
  • 很高兴你能成功!在 Passenger 和 Rails 2.3.x 中,这个问题似乎完全解决了。
【解决方案5】:

在 Rails 2.3 和 Mongrel 集群中也遇到过同样的问题,其中会话密码肯定是在会话初始化程序中设置的。清除客户端上的客户端 cookie 后仍出现此问题。

但是,在所有杂种动物重新启动后执行 curl get 请求的建议似乎可行 - 谢天谢地,有人发现了这一点,因为它似乎非常晦涩难懂。

我可以提供的唯一附加信息是我们在 Mongrels 前面使用 Apache mod_proxy_balancer 和 https,但是这个问题是在我们打开 SSL 之前发生的。有人用 haproxy 作为平衡器而不是 Apache 吗?

【讨论】:

    【解决方案6】:

    这为我解决了这个问题 :-) :-) :-)

    https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/4690-mongrel-doesnt-work-with-rails-238#ticket-4690-37 由 Mike Bethany 发布 2010 年 8 月 30 日下午 06:43。

    【讨论】:

    • 尝试在您的帖子中包含主要思想。其他网站可能会关闭。
    【解决方案7】:

    我从来没有费尽心思去弄清楚细节,但对我来说,这是一个客户端数据腐烂问题。如果我一直在搞乱我存储会话的方式(以及我的授权详细信息),我会不时收到此错误。清除私人浏览器数据; cookie,经过身份验证的会话,工作,总是为我解决它。

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2018-06-29
      • 1970-01-01
      • 2018-06-20
      • 2018-03-31
      • 2019-06-20
      • 1970-01-01
      • 2011-03-04
      • 2013-04-21
      • 2016-03-19
      相关资源
      最近更新 更多