代码之家  ›  专栏  ›  技术社区  ›  shedd

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

  •  17
  • shedd  · 技术社区  · 17 年前

    我们正在使用Engineyard云来部署我们的RubyonRails应用程序。我们正在运行2.3.3版的Rails。

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

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

    这是我们看到的错误:

    操作控制器::InvalidAuthenticityToken /usr/lib/ruby/gems/1.8/gems/actionpack-2.3.3/lib/action_controller/request_forgery_protection.rb:79:在“验证_真实性_令牌”中

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

    会议:

    • 会话ID:零
    • 数据:零

    我们还没能解释这一点。有没有想过什么是根本原因?

    谢谢你的建议!


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

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

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

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

    • 重置会话
    • 删除会话cookie(在javascript和rails中)
    • 部署代码后清除数据库中的会话表

    什么都不起作用。唯一有效的方法是让用户清除他们的cookie客户端。

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

    另外:最初我们认为这与我们对Engineyard的部署是孤立的,但我们也能够在开发服务器上复制它,我们通过Capistrano将其部署到该服务器上。

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

    谢谢!

    7 回复  |  直到 16 年前
        1
  •  13
  •   shedd    17 年前

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

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

    [有一个使用curl的潜在解决方案。]curl-work-around将对服务器上的每个Mongerl执行一个简单的get请求,以启动它们。您可以使用Capistrano来完成此操作,但如果通过仪表板部署,这将不起作用。您可以在下面的基础结构中找到有关部署挂钩的简短部分: https://cloud-support.engineyard.com/faqs/overview/getting-started-with-engine-yard-cloud

    添加简单的跑步曲线 http://localhost:500x >/dev/null应该可以工作(其中x是当前设置中的5000-50005端口)。

    我们已经解决了这个问题,将我们的堆栈从Mongrel切换到了Passenger,但显然,Mongrel的修复工作正在进行中。希望这能帮助那些看到同样奇怪问题的人。

        2
  •  10
  •   BaroqueBobcat    17 年前

    真实性令牌是表单上的一个隐藏字段,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 有关详细信息的文档

        3
  •  4
  •   Stephen Veiss    17 年前

    听起来,当您重新部署时,用于身份验证的密钥正在更改,从而使所有现有会话无效。

    你有配置参数吗 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
  •  1
  •   chris    17 年前

    如果它只会在那里为旺格!我在乘客身上也得到了完全相同的错误(用户加载表单、部署、提交->无效的真实性令牌)。知道你是如何通过切换到乘客来解决这个问题的,会很有趣吗?任何进一步的提示都是非常欢迎的。我也会仔细看看……

    干杯!

        5
  •  1
  •   moschops    16 年前

    在Rails2.3和一个mongrel集群中遇到了同样的问题,其中会话秘密在会话初始值设定项中被明确设置。即使在清除客户端上的客户端cookie之后,也会发生此问题。

    然而,在重新启动后,对所有Mongrel执行curl-get请求的建议似乎奏效了——谢天谢地,有人发现了这一点,因为它看起来相当模糊。

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

        6
  •  1
  •   SUzB    16 年前

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

    https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/4690-mongrel-doesnt-work-with-rails-238#ticket-4690-37 由迈克·贝萨尼发布 2010年8月30日下午6:43。

        7
  •  0
  •   Sniggerfardimungus    17 年前

    我从来没有花过多时间去弄清楚细节,但对我来说,这是客户端数据腐烂的问题。如果我一直在乱弄我存储会话的方式(因此,我的授权详细信息),我会不时地得到这个错误。清除私有浏览器数据;cookie、经过身份验证的会话和工作始终为我解决了这个问题。

    希望这有帮助。

    推荐文章