2015-10-15 148 views
2

我在正确实施OAuth时遇到了麻烦。 我使用客户端/ API架构(Angular为Front,Node.js为back),我希望用户仅使用Google OAuth身份验证进行登录。Google OAuth2流和id_token刷新

这里是什么,我认为是暂时的正确方法(告诉我,如果我误解的东西):

  • 角开一个谷歌弹出,询问用户的同意。
  • 一旦用户同意,Google授权服务器将发回验证码。
  • 此验证码被转发到API端点。
  • 然后,API要求Google授权服务器将此代码交换为access_token,id_token和refresh_token。
  • Google发送这3个令牌。
  • API使用的access_token从谷歌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过期,因为客户端没有任何刷新令牌?

谢谢!

回答

0

我这样做有点不同(尽管我有相同的基本架构)。

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

这样,我所有的敏感谷歌凭据(用户的OAuth令牌,如果需要的话,我的应用程序的API ID和秘密刷新令牌),仅是在服务器上,除了OAuth技巧继电器时,他们在在客户端重定向期间的URL字符串中。这是相当安全的。

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

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