Google Apps 和 OAuth 最佳实践


Google Apps and OAuth best practices

我正在努力将Google Apps集成到我的PHP应用程序中。我已经有一个登录系统,它将会话ID分配给用户(输入用户名和密码后(,该ID在用户登录时存储在数据库中。会话 ID 在一段时间不活动后变得无效(可由用户配置,可以是 5 分钟、15 分钟、60 分钟......该会话 ID 在 URL 中传递,以检查用户是否仍处于登录状态。注销时,会话 ID 将从数据库中删除。

我让人们通过将他们的谷歌ID存储在数据库中来登录谷歌,

当他们登录时,我请求访问令牌,查询用户信息,查看谷歌ID是否在数据库中,如果是,则为该用户分配一个会话ID。由于我希望能够查询其他API,因此我还在数据库中存储了访问令牌json。当用户注销时,访问令牌也会从数据库中删除。

这有效,我的用户可以使用他们的 Google 帐户登录,我可以使用存储的access_token查询 API,但是有些事情感觉很笨拙,让我对我的工作流程感到不确定:

  • 如果您force_approval得到一个refresh_token,我觉得我应该使用此刷新令牌来获取新的访问令牌,而不是从数据库中删除旧令牌并在用户再次登录时输入新令牌。另一方面,登录时,我还不知道是谁,所以我不知道要使用哪个刷新令牌。也许我误解了刷新令牌的用途。另外,我真的不想每次都强制批准,所以在这种情况下我什至不能使用refresh_token。

  • 如前所述,用户可以确定他们的会话将持续多长时间,但是,谷歌access_token总是在 3600 秒后过期。如果用户在系统上工作一个小时,然后Google API突然失败,迫使他们再次登录,那将是非常愚蠢的。 Google OAuth 游乐场显示一个复选框"在令牌过期前自动刷新令牌",但我看不到如何做到这一点。我必须在此处使用刷新令牌吗?或者只是在后台请求一个新令牌(如果我不强制批准(?

  • 目前,我正在使用用户信息查询(https://www.googleapis.com/oauth2/v2/userinfo(来查找用户ID,但我也可以使用tokeninfo(https://www.googleapis.com/oauth2/v1/tokeninfo(。Tokeninfo 未列在 oauth 操场中,但结果确实显示了令牌保持有效期的时间(但是,我也可以自己计算(。一个比另一个更可取吗?

  • 我将整个 json 对象存储在数据库中(access_token、id_token、expires_in 和 token_type(,但我觉得如果我只存储access_token,我的应用程序仍然可以完美运行(我预见的唯一问题是如果expires_in时间发生变化(。例如,我需要存储id_token吗?

我发现Google文档(developers.google.com(有时非常缺乏,如果有人知道任何其他好的信息来源,我也对它们感兴趣。

我认为

如果您查看最新的OpenID Connect Specs,其中像userinfo端点这样的概念来自其中,这可能会有所帮助。OpenID connect建立在OAuth 2之上。里面有很多东西,但仍然可能值得一看。这篇博客文章也非常好(同一博客中的其他文章也是如此(。

不幸的是,我不认为谷歌的实现目前与最新的规范草案保持同步,所以它可能在一段时间内成为一个移动的目标。在过去的一年里,这些事情发生了很大变化。

我同意您的第一点,即每次对用户进行身份验证时都应该获取新的访问令牌,而不是刷新旧令牌。在用户登录并授予您访问令牌之前,您不知道用户是谁。通常,访问令牌的生命周期不链接到用户的会话。一旦发出,您的应用程序理论上可以使用它来独立于用户的存在来访问资源。如果要在令牌到期时间之后继续访问资源,则需要在此时提交刷新令牌以获取新的访问令牌。恐怕我不知道"自动刷新"功能的用途。

我相信谷歌的tokeninfo类似于OpenID connect的check_id端点,但接受访问令牌或ID令牌,而不仅仅是后者。请注意,两者的到期时间可能不同。您通常能够从userinfo端点检索比从check_id更详细的用户数据,后者通常会返回裸user_id

您不需要存储id_token。它有点像授权服务器对用户身份验证的记录。访问令牌是验证用户标识后应用程序将有兴趣维护的内容。