谷歌应用与OAuth最佳实践

5
我正在将Google Apps集成到我的PHP应用程序中。我已经有一个登录系统,可以为用户分配会话ID(在输入用户名和密码后),当用户登录时,该ID将存储在数据库中。会话ID在一段时间内变得无效(由用户配置,可以是5分钟、15分钟、60分钟等)。会话ID通过URL传递以检查用户是否仍然登录。退出登录时,会话ID将从数据库中删除。
我让人们使用Google帐户登录,通过将其Google ID存储在数据库中,当他们登录时,我请求访问令牌,查询用户信息,查看数据库中是否有Google ID,如果有,则为此用户分配会话ID。由于我想能够查询其他API,我还将访问令牌JSON存储在数据库中。当用户退出登录时,访问令牌也将从数据库中删除。
这个方案可以工作,我的用户能够使用他们的Google帐户登录,并且我可以使用存储的access_token查询API,但有些地方感觉不顺畅或者让我对我的工作流程感到不确定:
- 如果你强制审批,你会得到一个refresh_token,我觉得我应该使用这个refresh_token来获取新的access_token,而不是在用户再次登录时删除旧的access_token并输入新的access_token。另一方面,当登录时,我还不知道是谁,所以我不知道要使用哪个refresh_token。也许我误解了refresh_token的用途。而且,我真的不想每次都强制批准,所以在那种情况下我甚至不能使用refresh_token。 - 如前所述,用户可以确定他们的会话持续多长时间,但是,Google access_token始终在3600秒后过期。如果用户在系统上工作了一个小时,然后Google API突然失败,迫使他们重新登录,那将非常愚蠢。 Google OAuth Playground显示一个复选框“在令牌到期之前自动刷新令牌”,但我不知道该如何做。我必须在这里使用refresh_token吗?还是在后台简单地请求新令牌(如果我没有强制批准)? - 目前,我正在使用userinfo查询(https://www.googleapis.com/oauth2/v2/userinfo)查找用户ID,但我也可以使用tokeninfo(https://www.googleapis.com/oauth2/v1/tokeninfo)。Tokeninfo没有在OAuth Playground中列出,但结果显示令牌保持有效的时间长度(但我也可以自己计算)。哪个更可取? - 我将整个JSON对象存储在数据库中(access_token、id_token、expires_in和token_type),但我认为如果我只存储access_token,我的应用程序仍将完美地工作(我预见的唯一问题是expires_in时间发生变化)。例如,我需要存储id_token吗?

我发现谷歌文档(在developers.google.com)有时非常缺乏,如果有人知道其他好的信息来源,我也感兴趣。

1个回答

4
我认为如果您查看最新的OpenID Connect Specs,其中包括userinfo端点等概念,可能会有所帮助。 OpenID Connect建立在OAuth 2之上。里面有很多内容,但仍然值得一看。这篇博客文章也非常好(同一博客中的其他文章也是如此)。
不幸的是,我认为Google的实现目前还没有更新到最新的规范草案,因此它可能会成为一个长期的移动目标。过去一年中,这些事情发生了很大变化。
我同意你的第一点,即每次认证用户时应获取新的访问令牌,而不是刷新旧的访问令牌。在用户登录并授予您访问令牌之前,您不知道用户是谁。一般来说,访问令牌的生命周期与用户会话无关。一旦发出,您的应用程序理论上可以使用它独立于用户的存在访问资源。如果您想在令牌过期时间之后继续访问资源,则需要在该点提交刷新令牌以获取新的访问令牌。很抱歉,我不知道“自动刷新”功能是什么。
我认为Google的tokeninfo类似于OpenID Connect的check_id端点,但接受访问令牌或ID令牌,而不仅仅是后者。请注意,两者的到期时间可能不同。通常,您可以从userinfo端点检索比从check_id更详细的用户数据,后者通常只返回裸的user_id
您不应该需要存储id_token。这有点像授权服务器对用户身份验证的记录。一旦验证了用户身份,访问令牌就是您的应用程序感兴趣的东西。

非常感谢您的建议,我会阅读您提供的文章,并希望它们能够帮助我在这条路上前进。 - Bram

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接