【发布时间】:2020-07-21 09:09:02
【问题描述】:
我正在设置 React SPA (www.mysite.com) 和 Rails API (api.mysite.com) 应用程序。当我使用相同的 URL 名称时,一切都按预期工作,但是当 URL 名称不同时,Web 浏览器不会设置站点 cookie。由于缺少 cookie,CSRF 验证当然也会失败。因此,例如,如果 SPA 应用程序在 localhost 上运行,Rails API 应用程序在 localhost:3000 上运行一切正常,那么问题仅在于我使用预期的 DNS 名称时。
听起来像是一个 CORS 问题,但我已经好几天找不到哪里了……
这是我的配置:
Rails 方面我正在使用rack-cors ruby gem
config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins 'localhost’, 'www.mysite.com',
resource '*',
headers: :any,
credentials: true,
methods: [:get, :post, :put, :patch, :delete, :options, :head]
end
end
Rails.application.config.action_controller.forgery_protection_origin_check = false
在 React 方面,我有 axios 配置如下:
src/App.js
axios.defaults.xsrfCookieName = "CSRF-TOKEN";
axios.defaults.xsrfHeaderName = "X-CSRF-Token";
axios.defaults.withCredentials = true;
当 React App 启动时,它会向 API 后端发出 GET 请求以获取 CSRF 令牌以供以后使用。同时浏览器应该设置站点cookies。
axios
.get("/sessions/csrf_token", {
headers: { "Content-Type": "application/json"
},
})
.then(response => {
// do stuff
});
});
当站点 cookie 设置和缺失时,两种情况下的响应标头看起来相同
我还可以看到 cookie 已发送到浏览器,但它们在 Cookies 部分下丢失了
非常感谢您对我在这里遗漏的任何想法! 谢谢!!
更新:
我还应该提到我的会话配置文件设置为允许子域
config/initializers/session_store.rb
Rails.application.config.session_store :cookie_store, key: '_mysite_session', expire_after: 8.hours, domain: :all, tld_length: 2
我的 cookie 配置可能有其他问题,但我不知道在哪里查看以及应该检查哪些其他设置。
这是我使用localhost 时我的 Cookie 窗格的屏幕截图,并且 cookie 按预期保留在浏览器中:
当我使用www.mysite.com 和api.mysite.com 名称时,右侧的窗格只是空的。
【问题讨论】:
-
这有点像在黑暗中拍摄,但是您是否尝试过在您的 rack-cors 配置中指定没有 WWW 的第二个域?无论如何,我们是否可以获取您的浏览器 cookie 窗格以及您正在谈论的那些真实域的源代码的图片?
-
@sevensidemarble 我试过没有 www 的域没有成功。一般来说,如果 CORS 设置以任何方式错误配置,axios 根本不会得到有效响应。在我的情况下,我没有看到任何错误,并且 API 调用返回了有效的 JSON 响应。唯一的问题是我的 cookie 窗格是空的。让我为帖子本身添加一个更新,并附上我希望 cookie 窗格看起来像的屏幕截图
-
我想我可能已经想通了,请在下面查看我的答案。
标签: ruby-on-rails cookies axios cross-domain csrf