【问题标题】:ActionDispatch::Cookies not setting Set-Cookie header in response but response.set_cookie doesActionDispatch::Cookies 没有在响应中设置 Set-Cookie 标头,但 response.set_cookie 确实
【发布时间】:2020-11-22 18:59:06
【问题描述】:

我有一个仅限 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) 何时设置标头作为响应?它发生在机架上吗?

要求

  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 协议发送它。我错过了什么?

【问题讨论】:

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


    【解决方案1】:

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

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

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

    虽然我没有找到任何关于这种行为的文档,但这就是它的工作原理。

    【讨论】:

      猜你喜欢
      • 2021-05-17
      • 2020-04-23
      • 1970-01-01
      • 2019-03-21
      • 2018-08-29
      • 2019-11-16
      • 2014-08-24
      • 2011-08-01
      • 1970-01-01
      相关资源
      最近更新 更多