ActionDispatch :: Cookies未在响应中设置Set-Cookie标头,但response.set_cookie可以

时间:2020-08-02 14:22:38

标签: ruby-on-rails ruby cookies actiondispatch rack-cors

我有一个仅Rails 5 API的应用程序,并希望在JSON请求的响应中发送cookie。当我使用ActionDispatch :: Cookies在请求的响应中设置cookie时,它没有在响应中设置Set-Cookie头。尽管response.set_cookie可以工作。

我还通过在应用程序控制器中制作一个after_action钩子进行了测试,发现在response.headers中没有Set-Cookie头,但是存在cookie ['name_of_cookie']。我还想问的一个问题是,这些cookie(ActionDispatch :: Cookies)何时设置响应头?它在机架中发生吗?

要求

  1. 我们要在CORS请求中设置Cookie。
  2. 我们要为所有来源的Cookie设置

已经实施了什么

  1. 客户端通过withCredentials发送请求
  2. 在响应中出现Access-Control-Allow-Credentials: trueAccess-Control-Allow-Origin: <origin (request.headers['origin'])>
  3. 因为它是仅限Rails API的应用程序,所以我们在该应用程序中包括以下中间件
config.middleware.use ActionDispatch::Cookies
config.middleware.use ActionDispatch::Session::CookieStore, key: '_namespace_key'

问题

  1. 为什么ActionDispatch :: Cookies不起作用,但response.set_cookie起作用?
  2. ActionDispatch :: Cookies何时设置响应头?它是否发生在rails应用程序中的任何after回调挂钩中,还是发生在机架中?因为直到applicaton_controller中的after_action头才出现。

奇怪

  1. 在开发环境中和在我的本地计算机上,它可以工作,但在生产中不起作用。它是否需要对Cookie的domain进行设置?我还在生产中使用了安全的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
)

我观察到一件事。如果我在Cookie中设置了secure: false,那么它将在生产环境中起作用,但在secure: true中则无效。另一方面,secure: true在生产中与response.set_cookie一起使用。

我的request.protocol是HTTP。如果请求协议为HTTP并且配置了secure: true选项,ActionDispatch :: Cookies是否可能甚至不设置cookie。

但是我认为secure: true是针对客户端的。就像cookie是安全的一样,浏览器将仅通过https协议发送它。我想念什么?

1 个答案:

答案 0 :(得分:0)

我有这种行为的原因。实际上,其他团队在生产中部署了application gateway。这导致Rails服务器收到最初为HTTPS的HTTP请求。

现在,由于我已将cookie标记为secure: true,如果协议是HTTP,则看起来ActionDispatch :: Cookies甚至不发送cookie来响应请求。仅当协议为HTTPS时才发送。如果我通过secure: false禁用了安全性,那么它将起作用,或者如果我禁用了应用程序网关,则它将与ActionDispatch :: Cookie一起使用。

secure是一个客户端属性,这似乎很奇怪,但是从ActionDispatch :: Cookies的行为来看,如果协议为HTTP并且将安全性设置为true,它甚至不从服务器发送cookie。 / p>

尽管我没有找到有关此行为的任何文档,但这是它的工作方式。