Google Oauth2 服务器端 web 应用程序的 CORS 问题

CORS issue with Google Oauth2 for server side webapps

我在 SO 上提到了这个问题: 但建议的解决方案是 Javascript 网络应用程序 使用 隐式授权流 .

我的设置是这样的,我的前端构建在 angular 4 上,但我将其打包并与其他 api 一起部署在同一台服务器上。 Si 我正在关注服务器端 Web 应用程序流程:https://developers.google.com/identity/protocols/OAuth2WebServer (下例中服务器端口为8300)

我已授权http://localhost:8300 as Javascript origin and making a request from an angular app to a rest api residing on http://localhost:8300/auth/oauth/test 但我仍然收到 CORS 错误:

Failed to load 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: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8300' is therefore not allowed access.

我的问题是

  1. 建议的解决方案是唯一的出路吗?
  2. Google API 页面上是否有一些我错过的配置?
  3. 如果我直接从浏览器 http://localhost:8300/auth/oauth/test 直接访问其余部分 api,一切正常。但是如果我从浏览器向这个 url 发出一个获取请求(因为它是安全的,重定向到 google api 应该发生,在身份验证之后,至少这个休息 api应该命中断点)。因为在这两种情况下,它都可以访问
    我最后的假设是错误的吗?

如果这是相关的,我正在做 angular get request like:

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);
        });

}

编辑

实际上,我的第 3 点是为什么在通过 XHR 从 angular 应用程序访问 rest api 时抛出 CORS,该应用程序也与 rest api 位于同一域而不是在 rest api 直接从浏览器访问。

当您使用授权代码授予(后端应用程序的 OAuth2 - &response_type=code)时,您必须将浏览器重定向到 /auth 端点 - 您不能为此使用 XHR。用户将在身份验证后被重定向回来。

重定向到 /auth 端点后,用户需要在地址栏中看到该页面来自 Google(可信来源)并且 Google 可能需要做更多的事情重定向以验证用户并显示同意页面。所以使用XHR是不可能的。

更新:对于第三点,如果请求不包含有效凭据(不是像现在这样的 HTTP 30x 重定向),您的后端 API 应该 return HTTP 401。然后,您的 Angular 应用程序需要一个 HTTP 错误处理程序,它会根据 HTTP 401 响应重定向浏览器。

但是如果您想在 Angular 应用程序中保留令牌,最好使用隐式授权,它是为浏览器中的应用程序 运行 设计的。因为使用授权代码授予,您的后端具有客户端的角色(在 OAuth2 方案中),但您希望 Angular 应用程序成为客户端(因为它持有令牌)。