Google OAuth2流程和id_token刷新

时间:2015-10-15 12:27:15

标签: angularjs oauth-2.0 google-oauth jwt google-oauth2

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

以下是我认为目前正确的方法(告诉我,如果我误解了某些内容):

  • Angular打开Goog​​le弹出窗口,询问用户的同意。
  • 用户同意后,Google授权服务器会向角度发送验证码。
  • 此验证码将转发到API端点。
  • 然后,API要求Google授权服务器将此代码替换为access_token,id_token和refresh_token。
  • Google发送了这3个令牌。
  • API使用access_token从Google API检索用户
  • API保留用户

这是小dillema,在我看来,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到期,因为客户端没有任何刷新令牌?

谢谢!

1 个答案:

答案 0 :(得分:0)

我做的略有不同(虽然我有相同的基本架构)。

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

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

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

如果您需要刷新令牌,可以在access_type=offline的初始请求中设置oauth2/auth,并且您将获得刷新令牌作为响应的一部分,除非您之前获得过刷新令牌。然后,您可以将其保留在服务器端,并根据需要获取新的访问令牌。如果你也设置了approval_prompt=force,你将强制一个新的同意屏幕并保证刷新令牌(但是在授予用户一些少量刷新令牌之后,旧版本会在同一个应用程序上到期,所以最好是只有在真的需要时才要求他们。