Rails – 部署后无效的真实性令牌

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

EngineYard Cloud以类似于Capistrano的方式部署到AWS实例。 每次部署后,我们都会遇到无效的真实性令牌错误。 具体而言,任何先前访问过我们的应用程序然后在部署后访问然后尝试提交表单的用户都会收到无效的真实性令牌错误。 在重置网站的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,check_authenticity_token’

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

会议:

  • 会话ID:无
  • 数据:无

我们无法解释这一点。 关于什么可能是根本原因的任何想法?

谢谢你的任何建议!


编辑:为了更新这一点,我们已经能够找出错误的一个例子。

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

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

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

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

什么都行不通。 唯一有效的方法是让用户清除客户端的cookie。

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

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

任何想法都会被感激地接受。

谢谢!

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

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

[有一个使用CURL的潜在解决方法。] curl解决方法会对服务器上的每个mongrel执行一个简单的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的修复正在进行中。 希望这可以帮助那些看到同样奇怪问题的人。

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

它是一种安全措施,可以防止恶意用户在其网站上使用表单提交对某人帐户的删除操作。

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

 config.action_controller.allow_forgery_protection = false 

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

 skip_before_filter :verify_authenticity_token 

或打开它

 protect_from_forgery :except => :index 

查看ActionController :: RequestForgeryProtection :: ClassMethods文档以获取更多详细信息

听起来,当您重新部署,使所有现有会话无效时,用于身份validation的密钥会发生变化。

你有配置参数config.action_controller.session设置在任何地方,如果你这样做,有什么可以导致它重新部署时改变?

我的一个应用程序在config/environment.rbconfig/environment.rb它,而一个更新的应用程序(使用Rails 2.3生成)在config/initializers/session_store.rb设置了它。 设置如下:

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

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

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

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

干杯!

在Rails 2.3和Mongrel集群中遇到了同样的问题,其中会话密钥肯定在会话初始化程序中设置。 即使在客户端上清除客户端cookie后,问题仍然存在。

然而,在重新启动之后对所有杂种进行curl获取请求的建议似乎有效 – 谢天谢地,有人认为这是因为它看起来很晦涩难懂。

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

我从来没有花时间去弄清楚细节,但对我来说,这是一个客户端数据腐烂问题。 如果我一直在搞乱我存储会话的方式(因此,我的授权细节),我会不时收到此错误。 清除私人浏览器数据; cookies,认证会议,作品,总是为我解决。

希望这可以帮助。