简体   繁体   English

CORS 问题与 window.open() 和 OAuth2

[英]CORS issues with window.open() and OAuth2

I'm running a site that uses SharedArrayBuffer (ffmpeg wasm) which strictly requires CORS (and/or site isolation), AND a Discord oauth2 workflow.我正在运行一个使用SharedArrayBuffer (ffmpeg wasm) 的站点,它严格要求 CORS(和/或站点隔离)Discord oauth2 工作流。 After not looking at the site since earlier this year, I found out that it no longer works on the latest version of Chrome.从今年早些时候开始就没有查看该网站后,我发现它不再适用于最新版本的 Chrome。 Eventually I figured out that the problem with the Discord oauth flow was related to CORS.最终查明Discord oauth流量的问题与CORS有关。

When using window.open() , (same-origin) CORS will prevent your site from interacting with said new window if it's on another domain (if I understand it right).使用window.open()时,(同源)CORS 将阻止您的网站与所述新的 window 交互,如果它在另一个域上(如果我理解正确的话)。 Checking the window promise returns that the window has closed ( window.closed == true ), even thought it hasn't.检查 window promise 返回 window 已经关闭( window.closed == true ),甚至认为它没有。

I signed up for Origin Trials (hoping that same-origin-allow-popups actually works soon).我注册了Origin Trials (希望same-origin-allow-popups尽快生效)。 That did fix the Discord part of the flow.确实修复了流程的 Discord 部分。 Checking the window promise returns normal.检查window promise返回正常。 BUT, once I get redirected back to my own site, it once again claims the window is closed (before I can get the oauth code).但是,一旦我被重定向回我自己的网站,它再次声称 window 已关闭(在我获得 oauth 代码之前)。

Why would CORS prevent me from reading my own site?为什么 CORS 会阻止我阅读我自己的网站? Is it because the previous document.domain was set to discord.com ?是不是因为之前的document.domain设置为discord.com

Does anyone know of any good ways to troubleshoot this kind of problem?有谁知道解决此类问题的任何好方法? CORS errors are common, but there are no CORS errors, just window.closed == true . CORS 错误很常见,但没有CORS 错误,只有window.closed == true

Short Answer : Check the Referer (spelling error is intentional) header in your request and response.简短回答:检查您的请求和响应中的Referer (拼写错误是故意的)header。 New Chromium based browsers (Chrome, Chromium and MS Edge) would return the URL to the origin due to its strict-origin new default policy.新的基于 Chromium 的浏览器(Chrome、Chromium 和 MS Edge)将返回 URL 到原点,因为它有严格的新默认策略。

There are multiple ways you can set the appropriate policies.您可以通过多种方式设置适当的策略。 I would not recommend using blanket "no-referrer" this could potentially be risky.我不建议使用笼统的“无推荐人”,这可能有风险。 "no-referrer-when-downgrade" could be a safer option. “no-referrer-when-downgrade”可能是一个更安全的选择。 Once this policy is set either programmatically or via configuration of your app, the browser will examine and send the redirect appropriately.一旦以编程方式或通过配置您的应用程序设置此策略,浏览器将检查并适当地发送重定向。

Long Read : In a nutshell chromium has enhanced the security, policy so unless referrer policy is defined in the request header, chromium the redirect would go to the source of origin.详细阅读:简而言之,chromium 增强了安全性,因此除非在请求 header 中定义了 referrer 策略,否则 chromium 会将 go 重定向到原始来源。

I ran into a similar issue where the redirection of oauth and back to the app would work as expected in IE but it would not work in the Chromium based browsers that is (Chrome, Chromium and MS Edge).我遇到了一个类似的问题,即 oauth 的重定向并返回到应用程序会在 IE 中按预期工作,但它不会在基于 Chromium 的浏览器(Chrome、Chromium 和 MS Edge)中工作。 Upon successful redirection from oauth provider, the redirection would go to the origin host.从 oauth 提供商成功重定向后,重定向将 go 到原始主机。

Here was my scenario这是我的场景

www.hostA.com (Origin)
www.hostB.com/search/product/123 (CORS destination)
www.oauth-provider.com (OAuth Provider)

Both hostA and hostB are behind the oauth authentication. hostA 和 hostB 都在 oauth 认证之后。 So when hostA is opening a request to hostB, the browser is setting the default policy "strict-origin" hence the referrer is added to the header which is "hostA" and redirects it to OAuth so user can supply credentials and Multi factor authentication etc.因此,当 hostA 打开对 hostB 的请求时,浏览器正在设置默认策略“strict-origin”,因此 referrer 被添加到“hostA”的 header 并将其重定向到 OAuth,以便用户可以提供凭据和多因素身份验证等.

When auth-provider receives the requests along with the policy header, it does the authentication and upon successful authentication it redirect it back to the browser along with original headers.当 auth-provider 收到请求以及策略 header 时,它会进行身份验证,并在身份验证成功后将其与原始标头一起重定向回浏览器。 Now browser looks at the referrer hence the URL becomes www.hostA.com/search/product/123 instead of www.hostB.com/search/product/123 , effectively falling back to the original request while keeping the rest of the URL intact.现在浏览器查看引荐来源网址,因此 URL 变为www.hostA.com/search/product/123而不是www.hostB.com/search/product/123 ,有效地回落到原始请求,同时保持 URL 的 rest 完好无损.

Solution : Setting the correct referrer policy on the originating application would fix this issue.解决方案:在原始应用程序上设置正确的引用策略可以解决此问题。 In my case it was a JavaScript Angular and specifying referrer policy in the window.open as a parameter worked.在我的例子中,它是一个 JavaScript Angular 并且在 window.open 中指定引用策略作为参数起作用。 However the policy can be defined/modified variety of ways like security filters, interceptors proxies etc depending whatever option is the safest.但是,可以通过多种方式定义/修改策略,例如安全过滤器、拦截器代理等,具体取决于最安全的选项。

Examples:例子:

Some additional reading that helped me find this tricky issue —一些额外的阅读帮助我找到了这个棘手的问题——

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

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