问题描述
我正试图在同一TLD上但生活在不同子域上的两个Rails应用之间共享Devise会话cookie,以进行身份验证。一个应用程序是v4.2.11.1,另一个应用程序是v6.0.3.2。我想登录Rails 4应用程序,并在Rails 6应用程序中访问经过身份验证的用户信息。在Rails 4应用程序中登录时,会话cookie的设置很好,但是在Rails 6应用程序中尝试访问会话cookie时,它似乎被完全清除/重置。
- 为两个应用正确设置了会话存储Cookie域,例如
BaseActivity
。 - 两个应用中的会话存储区
.example.com
都设置为tld_length
。 - 两个应用程序中的cookie序列化程序都设置为
2
。 - 我在两个应用程序中都使用相同的
:marshal
。在Rails 4应用程序中,它是通过secret_key_base
env var设置的。在Rails 6应用中,它是通过Rails凭证设置的,例如ENV['SECRET_KEY_BASE']
。 -
config/credentials/<env>.yml.enc
在两个应用程序中都是相同的。 - 我在两个应用程序中都使用了相同的Devise gem版本和初始化程序。
解决方法
在您的特定情况下,可能还会发生其他事情,但是毫无疑问,自Rails 4以来,您需要查看对会话cookie的两个向后不兼容的更改。
- Rails 5.2进行了更改,以将到期信息嵌入加密的cookie中。来自upgrade guide:
为了提高安全性,Rails现在将到期信息也嵌入到 加密或签名的Cookie值。
此新的嵌入信息使这些Cookie与 低于5.2的Rails版本。
如果您需要5.1或更早版本的Cookie可以读取,或者 仍在验证5.2部署并希望允许您回滚设置
Rails.application.config.action_dispatch.use_authenticated_cookie_encryption
到false
。
- Rails 6.0更改了在加密cookie中嵌入目的的功能。从 upgrade guide:
为了提高安全性,Rails将目的信息嵌入加密的文件中。 或签名的Cookie值。然后,Rails可以阻止试图 复制cookie的签名/加密值,并将其用作 另一个Cookie。
此新的嵌入信息使这些Cookie与 低于6.0的Rails版本。
如果您需要由Rails 5.2和更早版本读取cookie,或者您 仍在验证您的6.0部署并希望能够回滚 设置
Rails.application.config.action_dispatch.use_cookies_with_metadata
到false
。