session - rails session 被间歇性重置

标签 session heroku ruby-on-rails-4

我知道这个话题已经讨论了很多,但我相信我发现了它的一个新变体:我有一个 Rails 4 应用程序,它是从 Rails 3 升级的,它有 rails_ujscsrf_meta_tags正确设置。

曾经root_url加载到浏览器中后,有一个 javascript 会触发 GET 和 PUT,每个都针对应用程序中各自的 Controller API。当这 2 个 API 调用被触发时, session 应该具有 _csrf_token那里。大多数时候这是真的。继续阅读。

问题是,有时,并非总是如此,我们会看到 PUT 请求发生了一些 InvalidAuthenticityToken 异常。 (是的,我在我们的 API 基础 Controller 上使用 protect_from_forgery :with => :exception)。

分析来自 exception_notification 的转储,我可以看到CSRF_TOKEN在请求头中正确设置,但最有趣的是 session 只有 session_id在上面。其他一切都消失了,包括 _csrf_token .

请记住:这是间歇性发生的!所以我相信它一定是某种竞争条件。

此应用程序托管在 Heroku 上并在 Unicorn 上运行。我无法在本地环境中重现该问题。我还在 github 上阅读了很多 Rails 代码,试图了解它重置 session 的流程,但我找不到答案,因为所有 CSRF 保护都已正确设置并且问题间歇性发生。

还值得一提的是,我们没有设置 config.secret_key_base然而。但由于这个问题是间歇性发生的,我不认为这可能是它的根本原因。

另外,我认为值得一提的是,我们有两个 Controller 层次结构:

(1) 所有“正常”应用程序请求都通过继承自 ApplicationController 的 Controller 。

(2) 所有API请求都经过继承自Api::BaseController的 Controller ,后者继承自ActionController::Base直接地

我相信这个 Controller 方案对每个人来说都是最常见的......

GET 请求的 API 端点正在呈现 json 响应。 PUT 请求的 API 端点返回 head :ok .

好吧,如果有 Ruby on Rails 专家可以帮助解决这个问题,我会很高兴的。

最佳答案

您是否使用标准的基于 cookie 的 session 存储?我上次查看的基于 cookie 的 session 存储肯定会受到竞争条件的影响,尤其是在 AJAX 请求周围——而且竞争条件是基于 cookie 的 session 存储设计的固有部分,没有真正的修复它的方法。
This post from 2011描述了也涉及真实性 token 的 cookie 存储竞争条件,并且可能与您的类似。他们的解决方案是关闭 CSRF 保护,无论如何,对于某些操作,这对我来说听起来不是一个很好的解决方案。
This post from 2014概述了 cookie session 存储的竞争条件,并建议将 ActiveRecord 或其他服务器端存储作为解决方案。 (在我写这篇文章时,那个 URL 是 404'ing,但在谷歌缓存中可用)。

As you can see from the example, the session cookie is updated on every request, regardless of if the session was modified or not. Depending on when the response gets back to the client last, thats the cookie that will be used in the next call. For example, if in our previous example, if get_current_result’s response was slower than get_quiz, then our cookie would have the correct data and the next call to update_response would of work fine! So sometimes it will work and sometimes not all depending on the internet gods. This type of race condition is no fun to deal with.

The implications of this is that using cookie storage for sessions when you are doing multiple ajax call is just not safe. All information saved in the session might be wrong or nonexistent next time you check. So whats the solution?

...

A better solution would be to use a server side session store like active record or memcache. Doing so prevents the session data from being reliant on client side cookies. Session data no longer has to be passed between the client and the server which means no more potential race conditions when two ajax are simultaneously made!


我不能肯定地说您是否遇到了那个问题,但值得尝试切换到 ActiveRecord cookie 存储,看看您的问题是否消失。
甚至基于 activerecord 的 session 存储也位于 times in the past been subject to race conditions ,我不确定当前的实现是否是,但它们至少是可以想象的,而基于 cookie 的存储中的竞争条件是基本的。
实际上,ActiveRecord 存储可能会受到与 cookie 存储类似的竞争条件的影响——如果您有多个应用进程在运行(或多线程应用服务器),那么并发请求处理仍然是可能的,一个非常相似的竞争条件是可能还是有可能的。尽管它可能比 cookie 存储的竞争条件更罕见,并且理论上是可以解决的,尽管可能具有某些特定领域的逻辑,不像 cookie 存储的竞争条件,如果您正在执行任何异步操作,则几乎无法解决 Ajax 。

关于session - rails session 被间歇性重置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24440901/

相关文章:

php - $_SERVER ['HTTP_COOKIE' ] 返回的两个 PHPSESSID

r - 如何防止 Shiny 的应用程序变灰?

activerecord - 如何通过has_many通过关联使用Rails 4的强参数?

c# - Membership(+ roles) VS session state VS 表单认证

php - 使用 session 显示/隐藏 div (php)

java - 玩框架。从谷歌登录页面重定向后 session 变为空

ruby-on-rails - 在 Heroku 上的 ImageMagick 中使用自定义字体

sql - 如何在 heroku 上执行 .sql 脚本?

ruby-on-rails - 如何在 Rails 中创建具有 NULLS LAST 的索引?

ruby-on-rails - 如何隐藏 Rails 表单(Haml)中的标签?