Access-Control-Allow-Origin 等于 origin 但浏览器仍然拒绝访问......为什么? [英] Access-Control-Allow-Origin equals origin but the browser still denies access... why?

查看:19
本文介绍了Access-Control-Allow-Origin 等于 origin 但浏览器仍然拒绝访问......为什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  • Web 应用程序位于 foo.bar.com
  • 并与 api.foo.bar.commedia.foo.bar.com 交谈.

在访问 api.foo.bar.com 时,我收到来自浏览器(Edge、Chrome 或 Firefox)的错误消息,告诉我源 (foo.bar.com) 与 Access-Control-Allow-Origin 响应头的值不同.但是,通过检查响应,它们是相同的:

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

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

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

除此之外,我不知道哪里出了问题.有一点是肯定的,因为所有浏览器都同意我的请求应该被阻止(考虑到来源).

在所有情况下,我已经多次检查地址是否有拼写错误、结束正斜杠等.我已经使用 cURL 和 Postman 在这些端点上调用了 OPTIONS,使用所有标头或仅使用一些.他们总是回答正确的地址.


应要求提供的其他信息:

预检请求:

OPTIONS/media/1.0.0/rtsp/hls?feedUrl=https%3A%2F%2Flive.monuv.com.br%2Fa1%2F14298.stream%2Fstr27%2Fchunklist.m3u8%3Fm_hash%3DkhV_hCnFakZ3n99idQVHiQh80ADW78%253D HTTP/2主持人:media.aiXXXXXXXXXXXXXX.com用户代理:Mozilla/5.0(Windows NT 10.0;Win64;x64;rv:93.0)Gecko/20100101 Firefox/93.0接受: */*接受语言:en-US,en;q=0.5接受编码:gzip、deflate、br访问控制请求方法:GET访问控制请求头:feedurl推荐人:https://aiXXXXXXXXXXXXXXXX.com/来源:https://aiXXXXXXXXXXXXXXXX.comDNT:1连接:保持连接Sec-Fetch-Dest:空Sec-Fetch-Mode:corsSec-Fetch-Site:同站编译指示:无缓存缓存控制:无缓存TE:拖车

预检响应:

HTTP/2 204 无内容日期:2021 年 10 月 8 日星期五 13:33:10 GMTx-powered-by: Expressaccess-control-allow-origin: https://aiXXXXXXXXXXXXXXXXXX.com变化:起源访问控制允许凭据:true访问控制允许方法:GET、HEAD、PUT、PATCH、POST、DELETEaccess-control-allow-headers:内容类型,feedUrl严格传输安全:最大年龄=15724800;包含子域X-Firefox-Spdy:h2

请求

预检通过,浏览器开始飞行"请求:

GET/media/1.0.0/rtsp/hls?feedUrl=https%3A%2F%2Flive.monuv.com.br%2Fa1%2F14298.stream%2Fstr27%2Fchunklist.m3u8%3Fm_hash%3DkhV_hCnYZxBnoNCM99idQVHiQh80ADW78%253D HTTP/2主持人:media.aiXXXXXXXXXXXXXXXXXXXXX.com用户代理:Mozilla/5.0(Windows NT 10.0;Win64;x64;rv:93.0)Gecko/20100101 Firefox/93.0接受: */*接受语言:en-US,en;q=0.5接受编码:gzip、deflate、brfeedUrl:https://live.monuv.com.br/a1/14298.stream/str27/chunklist.m3u8?m_hash=khV_hCnKG3nhaNCFaYZxBnoMz-99idQVHiQh80ADW78%3D来源:https://aiXXXXXXXXXXXXXXXX.comDNT:1连接:保持连接推荐人:https://aiXXXXXXXXXXXXXXXXX.com/饼干:ory_kratos_session = MTYzMzYzODY1OHxEdi1CQkFFQ180SUFBUkFCRUFBQVJfLUNBQUVHYzNSeWFXNW5EQThBRFhObGMzTnBiXXXXXXXXXXXXYVc1bkRDSUFJSHBtUWxsaWFsVlJhWGRTVGxSMmIzZHRkbTFqYm5CUlRWVkdkelpPWkRoWnXXXTyqwgK-0Pe0qtZHjNhfU-YoASjg3istMZi672swQ ==Sec-Fetch-Dest:空Sec-Fetch-Mode:corsSec-Fetch-Site:同站编译指示:无缓存缓存控制:无缓存TE:拖车

回复

HTTP/2 302 发现日期:2021 年 10 月 8 日星期五 13:33:10 GMT内容类型:文本/纯文本;字符集=utf-8内容长度:129位置:https://api.aiXXXXXXXXXXXXXXXXXX.com/media/1.0.0/hls/streams/19dd149d-f551-4093-b2aa-e5558388d545/hls.m3u8x-powered-by: Expressaccess-control-allow-origin: https://aiXXXXXXXXXXXXXXXX.com变化:来源,接受访问控制允许凭据:true严格传输安全:最大年龄=15724800;包含子域X-Firefox-Spdy:h2

在此响应中,浏览器未能说明 originaccess-control-allow-origin 不匹配.

(第一张图片来自Edge,因为日志更清晰;此日志来自Firefox)

解决方案

问题

来自浏览器的错误消息(我在下面使用了虚拟 URL 和来源)可能有点令人困惑:

<块引用>

从源https://example.com"访问https://api.example.com/"(从https://media.example.com/"重定向)的 XMLHttpRequest 已被阻止CORS 政策:对预检请求的响应未通过访问控制检查:Access-Control-Allow-Origin"标头的值https://example.com"不等于提供的来源.

这里的关键是,正如 sideshowbarker 在 :它相当于使同源政策提供.

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

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

I have an application (React SPA) that calls a bunch of servers on different subdomains of the application domain, i.e.:

  • the web app sits at foo.bar.com,
  • and talks to api.foo.bar.com and media.foo.bar.com.

When accessing api.foo.bar.com, I get an error from the browser (be it Edge, Chrome, or Firefox) telling me that the origin (foo.bar.com) is different from the value of the Access-Control-Allow-Origin response header. However, by inspection of the response, they are the same:

(I unfortunately have to obfuscate the address.)

Those apps are hosted on Kubernetes; the ingress is NGINX, and it's is not providing CORS (cors-enabled annotation is false). Both applications (api and media) are Express apps, and both have the same CORS configuration allowing the specific origin.

I'm wondering if this has something to do with the redirect - the call to the media... endpoint returns a redirect (302) whose Location is a api... address.

Other than that, I have no clue what could be wrong. Something is, for sure, because all browsers agree that my request should be blocked (on account of the origin).

In all cases, I've checked the address multiple times for typos, ending forward-slashes, etc. I've called OPTIONS on those endpoints with cURL and Postman, using all headers or just a few. They always answer the correct address.


Additional information, as requested:

Preflight request:

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

Preflight response:

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

Request

The preflight passes, and the browsers starts a "flight" request:

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

Response

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

At this response, the browser fails saying that the origin don't match the access-control-allow-origin.

(the first image was from Edge, since the log was more clear; this log is from Firefox)

解决方案

Problem

The error message—I'm using dummy URLs and origins below—from the browser can be a bit confusing:

Access to XMLHttpRequest at 'https://api.example.com/' (redirected from 'https://media.example.com/') from origin 'https://example.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header has a value 'https://example.com' that is not equal to the supplied origin.

The key here is that, as sideshowbarker hinted at in his comment, because your first preflighted request to https://media.example.com/ responds with a cross-origin redirect to https://api.example.com/, the browser performs another whole CORS access-control check for that resource. However, because the redirect resulting from the first preflighted request happens to be cross-origin, the browser sets the origin of the second preflight request (which the error message refers to as the "supplied origin"), not as https://example.com, but as the null origin!

Here's a rundown of what is likely happening:

Because https://api.example.com likely doesn't (and shouldn't!) allow the null, the second access-control check fails and you get that annoying CORS error.

Solution

Resist the temptation to allow the null origin on https://api.example.com/, as doing so has serious security ramifications: it amount to voiding the protection that the Same-Origin Policy provides.

Instead, you should get rid of that redirect from https://media.example.com/ to https://api.example.com/ and make your frontend request the https://api.example.com/ resource directly.

Alternatively, if you cannot completely get rid of the redirect but you can change its destination, make it a same-origin redirect (from somewhere https://media.example.org to elsewhere on https://media.example.org).

这篇关于Access-Control-Allow-Origin 等于 origin 但浏览器仍然拒绝访问......为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆