【问题标题】:Access-Control-Allow-Origin response with ETag header seems to be getting cached despite response also having Vary: Origin带有 ETag 标头的 Access-Control-Allow-Origin 响应似乎正在被缓存,尽管响应也具有 Vary: Origin
【发布时间】:2021-12-08 22:10:46
【问题描述】:

我有一个 Rails API 为 mywebsite.com 和 app.mywebsite.com 提供服务,并配置了 rack-cors 以允许我向两者发出请求。 API 位于 api.mywebsite.com。

如果我从 mywebsite.com 调用端点,一切都会按预期工作。但是,如果我随后从 app.myswebsite.com 进行相同的调用,则会收到错误消息:

Access to fetch at 'https://api.mywebsite.com/api/v1/endpoint' from origin 'https://app.mywebsite.com' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header has a value 'https://mywebsite.com' that is not equal to the supplied origin.

我已经在 rack-cors 中设置了调试,并且可以看到正确的 Access-Control-Allow-Origin 正在发送正确的标头,但它似乎并没有发送到浏览器。

我发现如果我清除我的缓存,那么我可以成功地从 app.mywebsite.com 进行调用,但随后会收到来自 mywebsite.com 的错误:

Access to fetch at 'https://api.mywebsite.com/api/v1/endpoint' from origin 'https://mywebsite.com' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header has a value 'https://app.mywebsite.com' that is not equal to the supplied origin.

简而言之,我的浏览器似乎正在缓存它收到的第一个“Access-Control-Allow-Origin”标头。

我已阅读我需要设置 Vary 响应标头,但我已经将其设置为 Origin。

编辑: 来自工作请求 (mywebsite.com) 的请求标头

Accept: application/json
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Content-Type: application/json
Cookie: _my_website_session=abc123
Host: api.mywebsite.com
Origin: https://mywebsite.com
Referer: https://mywebsite.com/
sec-ch-ua: "Google Chrome";v="95", "Chromium";v="95", ";Not A Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36

来自工作请求的响应标头 (mywebsite.com)

Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE
Access-Control-Allow-Origin: https://mywebsite.com
Access-Control-Expose-Headers
Access-Control-Max-Age: 7200
Cache-Control: max-age=0, private, must-revalidate
Connection: Keep-Alive
Content-Type: application/json; charset=utf-8
Date: Fri, 22 Oct 2021 09:19:31 GMT
ETag: W/"ceb3066459b786782d836ac9e51cd349"
Keep-Alive: timeout=5, max=99
Referrer-Policy: strict-origin-when-cross-origin
Server: Apache
Set-Cookie: _my_website_session=abc123; path=/; HttpOnly
Transfer-Encoding: chunked
Vary: Origin
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Frame-Options: SAMEORIGIN
X-Permitted-Cross-Domain-Policies: none
X-Request-Id: 8fefc93c-b320-4276-acd4-8177b7745068
X-Runtime: 0.021539
X-XSS-Protection: 1; mode=block

来自错误请求 (app.mywebsite.com) 的请求标头:

Accept: application/json
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Content-Type: application/json
Cookie: _my_website_session=abc_123
Host: api.mywebsite.com
If-None-Match: W/"ceb3066459b786782d836ac9e51cd349"
Origin: https://app.mywebsite.com
Referer: https://app.mywebsite.com/
sec-ch-ua: "Google Chrome";v="95", "Chromium";v="95", ";Not A Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36

来自错误请求 (app.mywebsite.com) 的响应标头

Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE
Access-Control-Allow-Origin: https://mywebsite.com
Access-Control-Expose-Headers
Access-Control-Max-Age: 7200
Cache-Control: max-age=0, private, must-revalidate
Content-Type: application/json; charset=utf-8
Date: Fri, 22 Oct 2021 09:19:32 GMT
ETag: W/"ceb3066459b786782d836ac9e51cd349"
Referrer-Policy: strict-origin-when-cross-origin
Server: Apache
Set-Cookie: _my_website_session=abc123; path=/; HttpOnly
Vary: Origin
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Frame-Options: SAMEORIGIN
X-Permitted-Cross-Domain-Policies: none
X-Request-Id: 8fefc93c-b320-4276-acd4-8177b7745068
X-Runtime: 0.021539
X-XSS-Protection: 1; mode=block

编辑 2 Mac 上的 Chrome 存在此问题。在 Safari 上一切正常 我还可以看到请求正确地击中了控制器,这似乎只是用户代理中的响应问题。

【问题讨论】:

标签: cors apache2 rack-cors


【解决方案1】:

我终于明白了。

即使来源不同并且存在 Vary 标头并且如果 ETag 仍然匹配,Chrome 仍将使用缓存的标头。

要解决这个问题,要么取消设置 ETag 标头,要么根据请求来源改变它。

【讨论】:

  • 还有几个问题:您是否在为 https://api.mywebsite.com/api/v1/endpoint 路由发送的每个响应中都发送 Vary 响应标头?我的意思是,不仅适用于启用 CORS 的响应,而且适用于所有响应,无论如何。如果没有,你需要。
  • 顺便说一句,另一件事:如果我没记错的话,即使另一个响应标头发生了变化,您似乎也在发送相同的 ETag 标头。如果任何响应标头发生更改,则响应应获得不同的 ETag。
  • @sideshowbarker 是的,来自 API 的所有请求都存在 Very 标头。是的,你是对的,如果响应标头发生变化,ETag 应该发生变化。在这种情况下,我不需要缓存,因此使 ETag 不稳定工作正常。从长远来看,我可能需要回到这个问题并修复 ETag,但希望这个答案能够将面临相同问题的其他人指向正确的方向。
  • 好的,所以bugs.chromium.org/p/chromium/issues/detail?id=983532#c7 似乎很清楚问题中描述的内容是由具有相同 ETag 标头值的响应引起的,尽管它们具有不同的 Access-Control- Allow-Origin 标头值。
猜你喜欢
  • 1970-01-01
  • 2020-09-21
  • 2021-08-17
  • 1970-01-01
  • 2021-03-14
  • 2018-07-03
  • 2012-03-25
  • 2019-04-12
  • 1970-01-01
相关资源
最近更新 更多