cors - 尽管响应也有 Vary : Origin,但带有 ETag header 的 Access-Control-Allow-Origin 响应似乎已被缓存

标签 cors apache2 rack-cors

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

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

从源“https://app.mywebsite.com”获取“https://api.mywebsite.com/api/v1/endpoint”的访问已被 CORS 策略阻止:“访问” -Control-Allow-Origin' header 的值'https://mywebsite.com'不等于提供的来源。

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

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

从源“https://mywebsite.com”获取“https://api.mywebsite.com/api/v1/endpoint”的访问已被 CORS 策略阻止:“访问控制” -Allow-Origin' header 的值'https://app.mywebsite.com'不等于提供的来源。

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

我读到我需要设置 Vary 响应 header ,但我已经将其设置为 Origin。

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

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) 的响应 header

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

来自错误请求的请求 header (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

错误请求的响应 header (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 上一切正常 我还可以看到请求正确命中 Controller ,这只是用户代理中的响应似乎是问题所在。

最佳答案

我终于弄清楚了。

即使来源不同,并且如果 ETag 仍然匹配,Vary header 存在并设置为“Origin”,Chrome 仍将使用缓存 header 。

要解决此问题,请取消设置 ETag header 或根据请求来源更改它。

关于cors - 尽管响应也有 Vary : Origin,但带有 ETag header 的 Access-Control-Allow-Origin 响应似乎已被缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69673929/

相关文章:

ruby-on-rails - Rails 5.1 CORS - 如何为不同环境设置不同来源

ruby-on-rails - Rails 6、React、Rack-Cors

cors - 即使遵循 2 种方法,“访问控制允许来源”错误

angularjs - 在 AngularJS 中访问 JSONP 请求的真实 URL

typescript - CORS 预检 channel 在 Spring Security 中未成功

.htaccess/.htpasswd 如果位于某个 IP 地址则绕过

request - 预检请求不允许 POST 方法后,浏览器仍发送 HTTP POST 请求

ruby-on-rails - 乘客 RequestHandler 中的异常 Errno::EPIPE(断管)

PHP -> 函数调用中断页面

ruby-on-rails - ruby on rails - rack-cors 具有不同资源的多个来源