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

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

问题描述

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

  • 网络应用位于 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),其 Location 是一个 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_hCnKG3nhaNCFaYZxBnoMz-99idQVHiQh80ADW78%253D HTTP/2主持人:media.aiXXXXXXXXXXXXXXXXXX.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:同一站点Pragma:无缓存缓存控制:无缓存TE:拖车

预检响应:

HTTP/2 204 无内容日期:格林威治标准时间 2021 年 10 月 8 日星期五 13:33:10x-powered-by: Express访问控制允许来源:https://aiXXXXXXXXXXXXXXXXXX.com变化:起源访问控制允许凭据:真访问控制允许方法:GET、HEAD、PUT、PATCH、POST、DELETE访问控制允许标头:内容类型,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_hCnKG3nhaNCFaYZxBnoMz-99idQVHiQh80ADW78%253D HTTP/2主办方:media.aiXXXXXXXXXXXXXXXXXXXXXXXX.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:同一站点Pragma:无缓存缓存控制:无缓存TE:拖车

响应

HTTP/2 302 找到日期:格林威治标准时间 2021 年 10 月 8 日星期五 13:33:10内容类型:文本/纯文本;字符集=utf-8内容长度:129位置:https://api.aiXXXXXXXXXXXXXXXXXX.com/media/1.0.0/hls/streams/19dd149d-f551-4093-b2aa-e5558388d545/hls.m3u8x-powered-by: Express访问控制允许来源:https://aiXXXXXXXXXXXXXXXX.com变化:起源,接受访问控制允许凭据:真严格的传输安全:最大年龄=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/ 资源.

或者,如果您不能完全摆脱重定向但可以更改其目的地,请将其设为 same-origin 重定向(来自某处 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天全站免登陆