首页 > 解决方案 > ActionDispatch::Cookies 没有跨域设置

问题描述

我有一个与后端 Rails API 交互的前端 React SPA。在生产中,前端有一个域名mysecretsite.com,而后端与mysecretsite.io

我正在使用ActionDispatch::Cookies在浏览器中设置访问令牌,以便用户可以使用该令牌发出后续请求。

cookies.signed[:access_token] = { value: 'tmp_token_string', httponly: true, domain: :all }

当 React SPA 和 Rails API 都在一台计算机上的本地开发中运行时,它可以按预期工作。

在我分别在不同的服务器上部署了 React SPA 和 Rails API 之后,我注意到浏览器中没有正确设置 cookie。

我可以在开发模式下重现此类问题,我将 React SPA 放置在同一 LAN 内的另一台计算机上。

我曾尝试使用 React SPA 的字符串为开发环境或生产环境或只是配置ActionDispatch::Cookies参数,但它没有改变任何东西。domainIP:Port%w(.mysecretsite.com .mysecretsite.io)nil

我的 cookie 设置中可能会遗漏什么?

控制器/application_controller.rb

class ApplicationController < ActionController::API
    include ActionController::Cookies
end

配置/应用程序.rb

module RailsApp
   class Application < Rails::Application
       config.load_defaults 5.2
       config.api_only = true

       config.middleware.use ActionDispatch::Cookies
   end
end

24 小时后,我有一些额外的信息:

我查看了 Chrome 浏览器的响应标头。在使用 Rails API 在同一台计算机上运行的 React SPA 中,access_tokencookie 已正确设置。这是响应标头:

Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD
Access-Control-Allow-Origin: http://192.168.12.40:27511
Access-Control-Expose-Headers:
Access-Control-Max-Age: 1728000
Cache-Control: max-age=0, private, must-revalidate
Content-Type: application/json; charset=utf-8
ETag: W/"ebd48cd3b0ac4fa7ba23a4d40b8508a2"
Vary: Origin
X-Request-Id: 9aa588f0-8569-b1ca-901945962e87
X-Runtime: 0.064807

当 React SPA 在同一 LAN 内的另一台计算机上运行时,access_tokencookie 没有设置,就像在生产中发生的那样。这是响应标头:

Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD
Access-Control-Allow-Origin: http://192.168.12.50:27511
Access-Control-Expose-Headers:
Access-Control-Max-Age: 1728000
Cache-Control: max-age=0, private, must-revalidate
Content-Type: application/json; charset=utf-8
ETag: W/"ebd48cd3b0ac4fa7ba23a4d40b8508a2"
Vary: Origin
X-Request-Id: 9aa588f0-8569-b1ca-901945962e87
X-Runtime: 0.059074

在这两种情况下,Set-Cookie标头都丢失了,但其中一个成功设置了 cookie,而另一个失败。

标签: ruby-on-railsrubycookiesruby-on-rails-5

解决方案


我自己弄清楚了这个问题。我只是无法将.com域分配给 React API,而将.io域与 Rails API 关联。

问题是

您需要至少两个级别的域相同才能使用 cookie

跨多个 TLD 的 Cookie 中所述?

在开发环境中,当 React SPA 和 Rails API 运行在不同的主机上时,我的解决方法是分别为两个应用程序分配一个通用的本地域名。

首先,编辑/etc/hosts为:

192.168.12.40   mydevsite.com
192.168.12.10   api.mydevsite.com

其次,在 Rails API 应用程序中,将mydevsite.com:27511作为附加源添加到文件config/initializers/cors.rb中。并重启 Rails API 生效。

最后,更新 React SPA 和浏览器中的相关请求 URL。


24 小时后

我可以确认该问题在生产环境中也已解决,其中 Rails API 配置了新域名api.mysecretsite.com

但是,我仍然不知道为什么官方文档有一个设置示例domain: %w(.example.com .example.org),以及它们呈现什么样的用例。


推荐阅读