未跨域设置ActionDispatch :: Cookie

时间:2019-07-06 05:16:13

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

我有一个与后端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的domain字符串(用于开发环境)或IP:Port(用于生产环境)或仅使用%w(.mysecretsite.com .mysecretsite.io)来配置ActionDispatch::Cookies参数,例如nil,但没有任何改变。

我的Cookie设置中可能遗漏了什么?

controllers / application_controller.rb

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

config / application.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_token cookie。这是响应头:

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_token cookie,这与生产中发生的情况相同。这是响应头:

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,而另一个却失败了。

1 个答案:

答案 0 :(得分:1)

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

问题是

  

您必须至少具有两个相同级别的域才能使用Cookie

Cookies across multiple TLDs?

中所述

在开发环境中,当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

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