用于服务器端 Web 应用的 Google Oauth2 的 CORS 问题
Posted
技术标签:
【中文标题】用于服务器端 Web 应用的 Google Oauth2 的 CORS 问题【英文标题】:CORS issue with Google Oauth2 for server side webapps 【发布时间】:2018-08-02 04:05:49 【问题描述】:我在 SO 上提到了这个问题:Google oauth 400 response: No 'Access-Control-Allow-Origin' header is present on the requested resource 但建议的解决方案是针对 Javascript web 应用程序 使用 implicit grant flow。
我的设置是这样的,我的前端是基于 angular 4 构建的,但我将它打包并将其与 rest api 一起部署在同一台服务器上。 Si 我正在关注服务器端 Web 应用程序流程:https://developers.google.com/identity/protocols/OAuth2WebServer (下例中服务器端口为 8300)
我已授权 http://localhost:8300 作为 javascript 来源,并从 Angular 应用程序向位于 http://localhost:8300/auth/oauth/test 的 rest api 发出请求 但我仍然收到 CORS 错误:
加载失败 https://accounts.google.com/o/oauth2/v2/auth?client_id=568176070083-1lc20949a0q58l0rhmq93n95kvu8s5o6.apps.googleusercontent.com&redirect_uri=http://localhost:8300/auth/myauth/oauth/callback&response_type=code&scope=https://www.googleapis.com/auth/userinfo.email%20https://www.googleapis.com/auth/userinfo.profile&state=EUTZF8: 请求中不存在“Access-Control-Allow-Origin”标头 资源。因此不允许使用原点“http://localhost:8300” 访问。
我的问题是:
-
建议的解决方案是here,唯一的出路吗?
Google API 页面上是否有一些我错过的配置?
如果我直接从浏览器直接访问其余 api http://localhost:8300/auth/oauth/test,一切正常。但是,如果我从浏览器向这个 url 发出 get 请求(因为它是安全的,所以应该在身份验证后重定向到 google api,至少应该命中这个 rest api 断点)。因为在这两种情况下,它都可以访问
我的最后一个假设是错误的吗?
如果这是相关的,我正在做有角度的获取请求,例如:
loginWithGoogle()
console.log(" Login with oauth2 ");
let oauthUrl = "http://localhost:8300/auth/oauth/test";
return this.http.get(oauthUrl)
.subscribe(
res =>
this.onSuccess(res);
, error =>
this.onFailure(error);
);
编辑
实际上,我的第三点是为什么当通过 XHR 从 angular 应用程序访问 rest api 时会抛出 CORS,该应用程序也与 rest api 位于同一域中,而不是当直接从浏览器访问 rest api 时。
【问题讨论】:
你有没有解决过如何避免启动一个新的浏览器窗口?在新的浏览器窗口中打开授权后,我最终得到了回调。 @Spock。不幸的是,没有。 【参考方案1】:当您使用授权码授权(后端应用程序的 OAuth2 - &response_type=code
)时,您必须将浏览器重定向到 /auth
端点 - 您不能为此使用 XHR。用户在认证后会被重定向回来。
重定向到/auth
端点后,用户需要在地址栏中看到该页面来自 Google(可信来源),并且 Google 可能需要进行更多重定向以验证用户身份并显示同意页面.所以使用 XHR 是不可能的。
更新:对于第三点,如果请求不包含有效凭据(不是现在的 HTTP 30x 重定向),您的后端 API 应该返回 HTTP 401。然后,您的 Angular 应用程序需要一个 HTTP 错误处理程序,它将浏览器重定向到 HTTP 401 响应。
但是,如果您想将令牌保留在 Angular 应用程序中,最好使用为在浏览器中运行的应用程序设计的隐式授权。因为使用授权码授权,您的后端具有客户端的角色(在 OAuth2 方案中),但您希望 Angular 应用程序成为客户端(因为它持有令牌)。
【讨论】:
实际上我的第三点是为什么当通过 XHR 从同一域上的角度应用程序访问 rest api 而不是直接从浏览器访问 rest api 时会引发 CORS。 但是,如果您的 XHR 被重定向,它就会到达 Google。如果不是这样,请尝试从浏览器中包含一些日志。如果您的 Angular 应用程序与后端具有相同的来源,那么请求它应该没有 CORS 问题。 无法加载accounts.google.com/o/oauth2/v2/…: 否'Access-Control-Allow-Origin'请求的资源上存在标头。产地'localhost:8300'因此不允许访问。 所以这是我在更新的答案中描述的方式 - XHR 请求被重定向到谷歌,但它应该得到一个 HTTP 401 响应。以上是关于用于服务器端 Web 应用的 Google Oauth2 的 CORS 问题的主要内容,如果未能解决你的问题,请参考以下文章
Cometd vs ActiveMQ 用于实时 Web 应用程序的服务器端推送
在 Chrome 扩展程序中使用 Google 帐户进行服务器端身份验证