繁体   English   中英

使用 Apache 反向代理和来自上游服务的 304 的 Access-Control-Allow-Origin header 值不正确

[英]Incorrect Access-Control-Allow-Origin header value with Apache reverse proxy and 304 from upstream service

我有一种情况让我有点发疯。 我继承了一些基础设施,其中包括 Apache 2.2 反向代理和 DMZ 中的上游服务,该服务通过 REST API 提供资源。

不同子域上有两个应用程序通过反向代理请求相同的 JSON 资源。

当应用程序 #1 ( https://one.host.com ) 请求资源时,请求标头如下所示(根据 Chrome DevTools),并且我的资源按预期返回:

Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Host: rest.api.com
Origin: https://one.host.com
Referer: https://one.host.com/...
sec-ch-ua: " Not;A Brand";v="99", "Google Chrome";v="97", "Chromium";v="97"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36

响应标头如下所示:

Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: X-Requested-With, Referer, Origin, Content-Type, SOAPAction, Authorization, Accept
Access-Control-Allow-Methods: POST, GET, OPTIONS, HEAD
Access-Control-Allow-Origin: https://one.host.com
Access-Control-Max-Age: 1000
Cache-Control: max-age=0,must-revalidate
Connection: Keep-Alive
Content-Encoding: gzip
Content-Length: 1906
Content-Type: application/json;charset=UTF-8
Date: Tue, 18 Jan 2022 22:32:35 GMT
ETag: 7a58c125
Keep-Alive: timeout=5, max=100
Server
Vary: Origin
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block

如果我然后从应用程序 #2 请求相同的资源( https://two.host.com )我遇到 CORS 错误和标题看起来像这样(根据 Chrome DevTools)

Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Host: rest.api.com
If-None-Match: 7a58c125
Origin: https://two.host.com
Referer: https://two.host.com...
sec-ch-ua: " Not;A Brand";v="99", "Google Chrome";v="97", "Chromium";v="97"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36

和响应头:

Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: X-Requested-With, Referer, Origin, Content-Type, SOAPAction, Authorization, Accept
Access-Control-Allow-Methods: POST, GET, OPTIONS, HEAD
Access-Control-Allow-Origin: https://one.host.com
Access-Control-Max-Age: 1000
Cache-Control: max-age=0,must-revalidate
Content-Encoding: gzip
Content-Length: 1906
Content-Type: application/json;charset=UTF-8
Date: Tue, 18 Jan 2022 22:38:54 GMT
ETag: 7a58c125
Server
Vary: Origin
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block

请注意,第二组响应标头中的 Access-Control-Allow-Origin header 引用了错误的主机/源,这会导致 CORS 错误。

我的 Apache 反向代理设置标题如下:

<IfModule mod_headers.c>
  SetEnvIf Referer "^(?:http:\/\/|https:\/\/)[^\/]+" origin_is=$0
  Header set Access-Control-Allow-Origin %{origin_is}e 
  Header set Access-Control-Allow-Credentials true
  Header set Access-Control-Allow-Methods "POST, GET, OPTIONS, HEAD"
  Header set Access-Control-Allow-Headers "X-Requested-With, Referer, Origin, Content-Type, SOAPAction, Authorization, Accept"
  Header set Access-Control-Max-Age 1000
</IfModule>

当我查看我的 Apache 访问日志时,我会看到第一个请求的 200 或 304,并且总是看到第二个请求的 304。 我发现我的反向代理返回 304 很奇怪,但 Chrome DevTools 显示 200 响应(我在 Fiddler 中看到 304 与 Chrome 显示 200 的相同请求)。 如果我清除缓存并以相反的顺序发出请求,我会遇到同样的问题,但相反。 作为一种解决方法,我可以蛮力从响应标头中删除 ETag(似乎有效地禁用了缓存),但这是不可取的。

我想知道问题可能出在哪里/哪里? 上游服务是否应该不响应第二个请求的 304? header 是否没有从 RP 转发到上游服务? 我的 RP 是否应该从 304 响应中删除 ETag?

我弄清楚了问题所在。 它归结为使用旧版本的 Apache (v2.4.38) 作为我们的反向代理,它有一个错误导致 CORS 标头从 304 响应中剥离。 升级到 >=2.4.48 应该可以解决问题。

Details about the issue can be found at: https://bz.apache.org/bugzilla/show_bug.cgi?id=51223 https://bz.apache.org/bugzilla/show_bug.cgi?id=61820

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM