簡體   English   中英

ActionDispatch::Cookies 沒有在響應中設置 Set-Cookie header 但 response.set_cookie 確實

[英]ActionDispatch::Cookies not setting Set-Cookie header in response but response.set_cookie does

我有一個 Rails 5 API only 應用程序,想在 JSON 請求的響應中發送 cookies。 當我使用 ActionDispatch::Cookies 在請求的響應中設置 cookie 時,它不會在響應中設置Set-Cookie header。 盡管response.set_cookie確實有效。

我還測試了在應用程序 controller 中制作after_action掛鈎,我看到的是Set-Cookie header 不存在於 response.headers 中,但存在 cookies['name_of_cookie']。 我還想問的一個問題是這些 cookies(ActionDispatch::Cookies) 什么時候設置 header 作為響應? 它發生在機架中嗎?

要求

  1. 我們要在 CORS 請求中設置 cookies。
  2. 我們要為所有來源設置 cookies

什么已經實施

  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設置有關系嗎? 我還在生產中使用 secure 和 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
)

我觀察到一件事。 如果我在 cookies 中設置secure: false那么它可以在生產中使用,但不適用於secure: true 另一方面secure: true在生產中與 response.set_cookie 一起使用。

我的 request.protocol 是 HTTP。如果請求協議是 HTTP 並且配置了secure: true選項,ActionDispatch::Cookies 是否有可能甚至不設置 cookies。

但我認為secure: true是針對客戶端的。 就像如果 cookie 是安全的,那么瀏覽器只會通過 https 協議發送它。 我錯過了什么?

我得到了這種行為的原因。 實際上,其他團隊在生產中部署了一個application gateway 這導致 Rails 服務器收到 HTTP 請求,最初是 HTTPS。

Now as I have marked my cookies to be secure: true , it looks like ActionDispatch::Cookies does not even send cookies in response to a request if the protocol is HTTP. 僅當協議為 HTTPS 時才會發送。 如果我通過secure: false禁用安全,那么它可以工作,或者如果我禁用應用程序網關,那么它可以與 ActionDispatch::Cookie 一起工作。

看起來很奇怪,因為secure是客戶端屬性,但是從 ActionDispatch::Cookies 的行為來看,如果協議為 Z293C9EA246FF9985DC6F62A650F78986 並且設置為 true,它甚至不會從服務器發送 cookies。

雖然我沒有找到任何關於這種行為的文檔,但這就是它的工作方式。

面臨類似的問題,但 cookie 被作為 Header 傳遞。問題是session_expiry在啟動時設置( session_store.rb ),因為它來自不同的Time.zone ,這迫使瀏覽器在收到 cookie 后立即將其刪除創建。

相反,我使用expire_after: 20.minutes這讓它對我有用。

將此張貼在這里,以防萬一有人遇到類似問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM