我有一个仅限 Rails 5 API 的应用程序,并希望在响应 JSON 请求时发送 cookie。当我使用 ActionDispatch::Cookies 在请求的响应中设置 cookie 时,它不会Set-Cookie
在响应中设置标头。虽然response.set_cookie
确实有效。
我还测试了after_action
在应用程序控制器中制作一个钩子,我看到的是Set-Cookie
response.headers 中不存在标头,但存在 cookies['name_of_cookie']。我还想问的一个问题是,这些 cookie(ActionDispatch::Cookies) 何时设置标头作为响应?它发生在机架上吗?
要求
- 我们想在 CORS 请求中设置 cookie。
- 我们想为所有来源设置 cookie
已经实施的内容
- 客户端发送请求
withCredentials
- 在响应中
Access-Control-Allow-Credentials: true
并且Access-Control-Allow-Origin: <origin (request.headers['origin'])>
在场 - 由于它是 Rails API 唯一的应用程序,我们在应用程序中包含以下中间件
config.middleware.use ActionDispatch::Cookies
config.middleware.use ActionDispatch::Session::CookieStore, key: '_namespace_key'
问题
- 为什么 ActionDispatch::Cookies 不工作但 response.set_cookie 工作?
- ActionDispatch::Cookies 什么时候设置响应头?它发生在
after
Rails 应用程序的任何回调挂钩中,还是发生在机架中?因为直到after_action
在 applicaton_controller 中,标题都不存在。
奇怪的
- 在开发环境和我的本地机器上它可以工作,但不能在生产环境中工作。它是否与
domain
cookie的设置有关?我还在生产中使用安全和 httponly cookie,但在开发中只使用 httponly。
我在这里想念什么?我花了几天时间寻找问题,但找不到解决方法。任何线索都会非常有帮助。谢谢
编辑 1
cookies[@name.to_sym] = {
value: @value,
expires: @expire,
httponly: true,
same_site: 'None',
secure: false # It works when I set it to false but doesn't work with `true` in production. In development env it works with either one.
}
response.set_cookie(
@name.to_sym,
value: @value,
expires: @expire,
httponly: true,
secure: true
)
我观察到一件事。如果我secure: false
在 cookie 中设置,那么它可以在生产中使用,但不能用于secure: true
. 另一方面secure: true
,在生产中使用 response.set_cookie。
我的 request.protocol 是 HTTP。如果请求协议是 HTTP 并且secure: true
配置了选项,ActionDispatch::Cookies 是否可能甚至不设置 cookie。
但我认为secure: true
是针对客户端的。就像如果 cookie 是安全的,那么浏览器只会通过 https 协议发送它。我错过了什么?