Access-Control-Allow-Origin 等于 origin 但浏览器仍然拒绝访问...为什么?

Bru*_*ant 5 null redirect cors preflight

我有一个应用程序(React SPA),它调用应用程序域的不同子域上的一堆服务器,即:

  • 网络应用程序位于foo.bar.com,
  • api.foo.bar.com并与和交谈media.foo.bar.com

访问 时api.foo.bar.com,我从浏览器(无论是 Edge、Chrome 还是 Firefox)收到错误消息,告诉我 origin ( foo.bar.com) 与响应标头的值不同Access-Control-Allow-Origin。然而,通过检查响应,它们是相同的:

在此输入图像描述

(不幸的是,我不得不混淆地址。)

这些应用程序托管在 Kubernetes 上;入口是 NGINX,并且它不提供 CORS(启用 cors 的注释为 false)。这两个应用程序 (apimedia) 都是 Express 应用程序,并且都具有允许特定来源的相同 CORS 配置。

我想知道这是否与重定向有关 - 对media...端点的调用返回一个重定向(302),其位置是一个api...地址。

除此之外,我不知道可能出了什么问题。有些事情是肯定的,因为所有浏览器都同意我的请求应该被阻止(由于来源)。

在所有情况下,我都会多次检查地址是否有拼写错误、结尾的正斜杠等。我使用OPTIONScURL 和 Postman 调用这些端点,使用所有标头或仅使用其中几个标头。他们总是回答正确的地址。


根据要求提供额外信息:

飞行前请求:

OPTIONS /media/1.0.0/rtsp/hls?feedUrl=https%3A%2F%2Flive.monuv.com.br%2Fa1%2F14298.stream%2Fstr27%2Fchunklist.m3u8%3Fm_hash%3DkhV_hCnKG3nhaNCFaYZxBnoMz-99idQVHiQh80ADW78%253D HTTP/2
Host: media.aiXXXXXXXXXXXXXX.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Access-Control-Request-Method: GET
Access-Control-Request-Headers: feedurl
Referer: https://aiXXXXXXXXXXXXXXXX.com/
Origin: https://aiXXXXXXXXXXXXXXXX.com
DNT: 1
Connection: keep-alive
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
Pragma: no-cache
Cache-Control: no-cache
TE: trailers
Run Code Online (Sandbox Code Playgroud)

飞行前响应:

HTTP/2 204 No Content
date: Fri, 08 Oct 2021 13:33:10 GMT
x-powered-by: Express
access-control-allow-origin: https://aiXXXXXXXXXXXXXXXXXX.com
vary: Origin
access-control-allow-credentials: true
access-control-allow-methods: GET,HEAD,PUT,PATCH,POST,DELETE
access-control-allow-headers: Content-Type, feedUrl
strict-transport-security: max-age=15724800; includeSubDomains
X-Firefox-Spdy: h2
Run Code Online (Sandbox Code Playgroud)

要求

预检通过,浏览器启动“飞行”请求:

GET /media/1.0.0/rtsp/hls?feedUrl=https%3A%2F%2Flive.monuv.com.br%2Fa1%2F14298.stream%2Fstr27%2Fchunklist.m3u8%3Fm_hash%3DkhV_hCnKG3nhaNCFaYZxBnoMz-99idQVHiQh80ADW78%253D HTTP/2
Host: media.aiXXXXXXXXXXXXXXXXXXXXX.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
feedUrl: https://live.monuv.com.br/a1/14298.stream/str27/chunklist.m3u8?m_hash=khV_hCnKG3nhaNCFaYZxBnoMz-99idQVHiQh80ADW78%3D
Origin: https://aiXXXXXXXXXXXXXXXX.com
DNT: 1
Connection: keep-alive
Referer: https://aiXXXXXXXXXXXXXXXXX.com/
Cookie: ory_kratos_session=MTYzMzYzODY1OHxEdi1CQkFFQ180SUFBUkFCRUFBQVJfLUNBQUVHYzNSeWFXNW5EQThBRFhObGMzTnBiXXXXXXXXXXXXYVc1bkRDSUFJSHBtUWxsaWFsVlJhWGRTVGxSMmIzZHRkbTFqYm5CUlRWVkdkelpPWkRoWnXXXTyqwgK-0Pe0qtZHjNhfU-YoASjg3istMZi672swQ==
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
Pragma: no-cache
Cache-Control: no-cache
TE: trailers
Run Code Online (Sandbox Code Playgroud)

回复

HTTP/2 302 Found
date: Fri, 08 Oct 2021 13:33:10 GMT
content-type: text/plain; charset=utf-8
content-length: 129
location: https://api.aiXXXXXXXXXXXXXXXXXX.com/media/1.0.0/hls/streams/19dd149d-f551-4093-b2aa-e5558388d545/hls.m3u8
x-powered-by: Express
access-control-allow-origin: https://aiXXXXXXXXXXXXXXXX.com
vary: Origin, Accept
access-control-allow-credentials: true
strict-transport-security: max-age=15724800; includeSubDomains
X-Firefox-Spdy: h2
Run Code Online (Sandbox Code Playgroud)

在此响应中,浏览器失败并指出originaccess-control-allow-origin.

浏览器日志

第一张图来自Edge,因为日志更清晰;这个日志来自Firefox

jub*_*0bs 7

问题

\n

浏览器中的错误消息\xe2\x80\x94I\m​​ using dummy URLs and origins below\xe2\x80\x94可能有点令人困惑:

\n
\n

从源“https://example.com/”访问“https://api.example.com/”(从“https://media.example.com/”重定向)的 XMLHttpRequest 具有被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:“Access-Control-Allow-Origin”标头的值“https://example.com”不相等到提供的原产地。

\n
\n

这里的关键是,正如 sideshowbarker 在他的评论中暗示的那样,因为您的第一个预检请求以跨源重定向https://media.example.com/响应,浏览器会对该资源执行另一个完整的 CORS 访问控制检查。但是,由于第一个预检请求产生的重定向恰好是cross-origin,因此浏览器将第二个预检请求的来源(错误消息将其称为“提供的来源”)设置为 origin 而不是as 。https://api.example.com/https://example.comnull

\n

以下是可能发生的情况的概要:

\n

在此输入图像描述

\n

因为https://api.example.com可能不允许(也不应该!)允许null,第二个访问控制检查会失败,并且您会收到恼人的 CORS 错误。

\n

解决方案

\n

抵制允许null起源于 的诱惑https://api.example.com/,因为这样做会产生严重的安全后果:这相当于使同源策略提供的保护失效。

\n

相反,您应该摆脱从https://media.example.com/to的重定向https://api.example.com/,并让您的前端https://api.example.com/直接请求资源。

\n

或者,如果您无法完全摆脱重定向,但可以更改其目的地,请将其设为同源重定向(从某处https://media.example.org到其他地方https://media.example.org)。

\n