【问题标题】:Google OAuth2 flow and id_token refreshGoogle OAuth2 流程和 id_token 刷新
【发布时间】:2016-01-13 21:55:30
【问题描述】:

我无法以正确的方式实施 OAuth。 我使用客户端/API 架构(前端为 Angular,后端为 Node.js),我希望用户仅使用 Google OAuth 身份验证登录。

这是我认为目前正确的方法(如果我误解了什么,请告诉我):

  • Angular 打开一个谷歌弹出窗口,征求用户的同意。
  • 一旦用户同意,谷歌授权服务器就会向 Angular 发送一个验证码。
  • 此验证码被转发到 API 端点。
  • 然后,API 要求 Google 授权服务器将此代码交换为 access_token、id_token 和 refresh_token。
  • Google 发送这 3 个令牌。
  • API 使用 access_token 从 Google API 检索用户
  • API 持久化用户

这是一个小难题,在我看来,access_token 和 refresh_token 应该存储到数据库中,id_token 应该发送回 Angular 客户端。 这样,它将允许 API 在 Google API 中请求资源,并且如果令牌过期,由于 refresh_token,它仍然可以请求新令牌。 在客户端,id_token 嵌入在所有请求中,因此允许 API 识别客户端并使用来自 https://www.googleapis.com/oauth2/v3/certs 的 Google 证书验证他的身份验证。

假设这是使用令牌的正确方法,由于客户端没有任何刷新令牌,我该如何处理 id_token 过期?

谢谢!

【问题讨论】:

    标签: angularjs oauth-2.0 jwt google-oauth


    【解决方案1】:

    我的做法略有不同(不过我的基本架构相同)。

    • Angular 决定用户需要登录并显示一个登录弹出窗口。
    • 登录弹出窗口中的 url 由 Angular 提供服务,而是直接从后端服务器运行:/auth/google。 (我个人使用 hapijs 和 bell)。
    • /auth/google 由铃铛插件提供服务并启动 OAUTH 舞蹈。
    • OAUTH 舞蹈的结束导致我的节点服务器生成一个本地令牌(我只是生成随机字节并将它们存储在映射到用户 ID 的 redis 中)
    • 因为初始登录弹出窗口是由 window.open 创建的,所以成功页面(在 api 端而不是 angular 生成)可以使用 window.opener.postMessage 将令牌传回 angular 运行时。

    这样,我所有敏感的谷歌凭据(用户的 oauth 令牌、刷新令牌(如果需要)以及我的应用程序的 api ID 和机密)都只在服务器上,除了在 OAUTH 舞蹈接力期间,当它们在 URL 中时客户端重定向期间的字符串。这是相当安全的。

    然后对于所有与 api 的实际用户交互,我使用我在第四步中生成的令牌进行身份验证。如果您愿意,这可能是 JWT,但我不会那样做;我只是使用redis从'longrandostring'-> userId映射。如果我擦除存储了所有令牌的 redis 数据库,这让我(例如)强制所有人重新登录,或者我可以编写一个 lua 脚本来删除映射到某个用户 ID 的所有条目。

    如果您需要刷新令牌,您可以在初始请求中将access_type=offline 设置为oauth2/auth,并且您将获得一个刷新令牌作为响应的一部分,除非您之前已经获得了刷新令牌。然后,您可以将其保存在服务器端并根据需要获取新的访问令牌。如果您也设置了approval_prompt=force,您将强制使用新的同意屏幕并保证刷新令牌(但在向用户授予少量刷新令牌后,旧令牌在同一应用程序上过期,因此最好只请求如果真的需要的话)。

    【讨论】:

      猜你喜欢
      • 2017-01-11
      • 2019-01-19
      • 2021-08-26
      • 2015-02-01
      • 1970-01-01
      • 2016-08-03
      • 2016-11-18
      • 2020-07-08
      • 2021-08-27
      相关资源
      最近更新 更多