【发布时间】:2014-06-26 21:56:45
【问题描述】:
我知道这个话题已经讨论了很多,但我相信我已经找到了它的一个新变体:我有一个 Rails 4 应用程序,它是从 Rails 3 升级而来的,它有 rails_ujs 和csrf_meta_tags 设置正确。
一旦root_url 被加载到浏览器中,就会有一个javascript 触发一个GET 和一个PUT,每一个都指向应用程序中各自的控制器API。当这 2 个 API 调用被触发时,会话应该有 _csrf_token 那里。这是真的,大多数时候。继续阅读。
问题在于,有时,并非总是如此,我们会看到 PUT 请求发生了一些 InvalidAuthenticityToken 异常。 (是的,我在我们的 API 基础控制器上使用 protect_from_forgery :with => :exception)。
分析来自exception_notification 的转储,我可以看到CSRF_TOKEN 在请求标头中设置正确,但最有趣的是会话上只有session_id。其他所有内容都消失了,包括 _csrf_token。
请记住:这是间歇性发生的!所以我相信它一定是某种竞争条件。
此应用托管在 Heroku 上并在 Unicorn 上运行。我无法在本地环境中重现该问题。我还在 github 上阅读了很多 Rails 代码,试图了解它重置会话的流程,但我找不到答案,因为所有 CSRF 保护都设置正确并且问题间歇性发生。
还值得一提的是,我们还没有设置config.secret_key_base。但由于这个问题是间歇性发生的,我不认为这可能是它的根本原因。
另外,我认为值得一提的是我们有两个控制器层次结构:
(1) 所有“正常”应用程序请求都通过继承自 ApplicationController 的控制器
(2)所有API请求都经过控制器,控制器继承自Api::BaseController,直接继承自ActionController::Base
我相信这种控制器方案对每个人来说都是最常见的......
GET 请求的 API 端点正在呈现 json 响应。 PUT 请求的 API 端点正在返回 head :ok。
嗯,如果有 Ruby on Rails 专家可以提供帮助,我会很高兴的。
【问题讨论】:
-
你有没有得到任何地方?
-
还没有...我仍然面临这个问题。你见过类似的东西吗?
-
我已经坚持了好几天了 - 设法将其缩小到根本没有设置会话的事实......我已经尝试了很多东西来修复原始问题,这将需要一段时间来回过头来。
-
我做了很多研究,但我找不到任何解决方案......不过,我认为我不是唯一面临这个问题的人。怎么没有人看到这种情况发生?我相信它与 Heroku 上不同 dynos 提供的请求有关,但我不知道如何在本地重现。
标签: session heroku ruby-on-rails-4