Google Home 授权代码和使用 Google 帐户进行身份验证
Posted
技术标签:
【中文标题】Google Home 授权代码和使用 Google 帐户进行身份验证【英文标题】:Google Home Authorization Code and Authentication with Google Account 【发布时间】:2018-11-28 14:31:57 【问题描述】:我目前正在尝试使用 Google Home 操作对 Google 帐户进行身份验证,并从凭据中检索授权码。我确实不想要访问令牌,但想要授权码。
我查看了this post 并发现 Google 已经更新了他们的政策并且不再允许他们自己的 OAuth 端点用于帐户链接授权代码流:
使用 OAuth 实现帐户关联时,您必须拥有自己的 OAuth 端点
话虽如此,
-
使用我的操作和必要的范围对现有 Google 用户进行身份验证的正确方法是什么? (我需要访问日历)
是否可以在不必创建自己的 OAuth2.0 端点的情况下进行此身份验证?
从这个流程中,是否可以提取授权码?
【问题讨论】:
为什么需要授权码? 【参考方案1】:目前通过用户的 Google 帐户对用户进行身份验证的方法是使用 Google Sign-In for Assistant。一旦他们登录到您的 Action,您将获得一个 id 令牌,您可以对其进行解码以获取他们的 Google ID,您可以使用它在您的数据存储区中查找他们的帐户以获取他们的访问/刷新令牌。
由于您需要其他范围,如果用户登录到 Google 助理并且尚未将范围附加到他们的帐户,您会将他们重定向到基于 Web 的登录页面,他们可以在其中使用 Google Sign 登录 -在您需要的范围内。在这种情况下,当他们通过网络登录并授权访问时,您将获得验证码,您将需要该验证码来交换验证令牌和刷新令牌并存储这些。
您不需要为此创建自己的 OAuth 端点,但您需要做一些额外的工作以确保它们被重定向到您的网站以在必要时进行授权。
当他们登录并授权您时,您只会获得一次的授权码。您需要将其交换为身份验证和刷新令牌,然后存储这些令牌。
更新以更好地解释事情。
查看架构,我们看到它有几个组件。在处理流程时,我们将详细介绍其中的每一项:
您有某种数据存储,您将在其中存储用户的 Auth Token 和 Refresh Token。我将假设您使用 Google 的用户 ID 作为此数据存储的索引。
在这种情况下,“Google 用户 ID”是指 Google 分配给每个帐户的唯一数字标识符。这通常表示为字符串,尽管只有数字,因为它通常比大多数数字类型长得多。在 ID Token 中,这是“sub”声明。
理论上,您可以使用 ID 令牌中的声明中可用的其他标识符,例如他们的电子邮件地址。不幸的是,并非所有这些字段都保证可用 - 只有“子”是保证的。
您有一个 Web 服务器,其中包含一些用于我们目的的重要 URL:
用于执行操作的 webhook。 登录/验证页面。 登录页面上的 javascript 将向您发送验证码的端点。可以在 Google Home 或移动设备上运行的 Google 助理。我们还假设用户将能够访问浏览器来查看他们正在授权的内容。
您将使用的 Google 服务,包括 Google 的 OAuth 服务
让我们从用户之前登录并授权我们代表他们访问服务的情况开始。我们的数据存储中有他们的 Auth Token 和 Refresh Token,根据他们的 Google 用户 ID 编制索引。这是一个简单的例子,但它可以帮助我们理解更复杂的情况,即所有数据是如何进入那里的。
数据流看起来像这样:
-
Assistant 向 Action webhook 发送 Intent 和可能的参数。如果这是第一条消息,这是一个受欢迎的意图,但没关系。它包括一个身份令牌,我们需要对其进行解码和验证。作为我们解码时获得的数据的一部分,它包括用户的用户 ID。
使用用户 ID...
...我们从数据存储中获取 Auth Token 和 Refresh Token。
使用 Auth Token 和 Refresh Token,我们可以代表用户对 Google 的服务执行一些操作。
我们将从服务中获取一些结果...
...我们通常希望以某种形式传回给用户。
很简单,对吧?但是,如果用户以前从未使用过 Assistant 与我们的 Action 对话怎么办?并且从未授权我们访问他们的谷歌服务,所以我们没有他们的令牌?该流程看起来更像这样:
-
助手向 Action webhook 发送 Intent 和可能的参数。这将是第一条消息,因此我们的欢迎意图被触发。没有身份令牌。
webhook 发现没有身份令牌,因此它发回一条消息,请求“登录”帮助程序功能。由于您的项目已配置为使用 Google 登录,因此 Google 助理会提示用户是否可以向您提供他们的个人资料信息。
如果他们说是,您会收到另一条回复,说明他们已登录并包含身份令牌,我们会对其进行解码和验证并获取他们的用户 ID。 (如果他们说不,我们会收到回复说它失败了。你如何处理这是另一回事。我假设他们说是。)
使用用户 ID...
...我们尝试从数据存储中获取 Auth Token 和 Refresh Token。但是他们还没有授权我们。我们对它们进行了身份验证,但没有授权...
...所以我们发回一条消息说他们需要访问我们的网站以授权我们访问他们的 Google 服务。我们可能会要求他们切换到移动设备来完成这部分工作,甚至包括登录页面的链接。
他们会在有屏幕的设备上点击链接。
我们将发回登录页面,其中包含一个使用 Google 登录的链接。我们已将此按钮配置为还要求我们提供访问其服务所需的其他范围,以及在“离线”时代表他们访问服务的权限。
他们将通过 Google 登录舞蹈、OAuth 范围屏幕,并希望授予我们想要的所有权限。 (再一次,我忽略了如果他们不这样做会发生什么。)我省略了那个舞蹈的样子,因为它不涉及我们。假设一切顺利,Google 会给他们一个 Auth Code,登录页面上的 javascript 会将其发送给我们。
我们调用 Google 的 OAuth 服务器来验证 Auth Code 并使用它来获取 Auth Token 和 Refresh Token...
……然后我们将其存储在数据存储中……
…然后发回一些内容,以便 Javascript 页面可以告诉用户他们可以从现在开始正常使用我们的操作。
他们现在可以做什么,并且它的行为与之前的简单场景一样。
这看起来很复杂,但事实证明我们可以在某些情况下删除一些步骤。如果 Google Cloud 项目与您用于操作和基于 Web 的 Google 登录的项目相同,那么一旦他们在 Web 上授权该项目,对您的履行的所有调用都将包括身份令牌。这让我们可以删除上面的步骤 2-6,所以事情看起来更像这样:
-
助手向 Action webhook 发送 Intent 和可能的参数。这将是第一条消息,因此我们的欢迎意图被触发。没有身份令牌。
webhook 发现没有身份令牌,因此我们发回一条消息,说他们需要访问我们的网站以授权我们访问他们的 Google 服务。我们可能会要求他们切换到移动设备来执行此部分,甚至包括登录页面的链接。 (这是上面折叠的第 2 步和第 6 步。)
他们会在有屏幕的设备上点击链接。
我们将发回登录页面,其中包含一个使用 Google 登录的链接。我们已将此按钮配置为还要求我们提供访问其服务所需的其他范围,以及在“离线”时代表他们访问服务的权限。
他们将通过 Google 登录舞蹈、OAuth 范围屏幕,并希望授予我们想要的所有权限。 (再一次,我忽略了如果他们不这样做会发生什么。)我省略了那个舞蹈的样子,因为它不涉及我们。假设一切顺利,Google 会给他们一个 Auth Code,登录页面上的 javascript 会将其发送给我们。
我们调用 Google 的 OAuth 服务器来验证 Auth Code 并使用它来获取 Auth Token 和 Refresh Token...
……然后我们将其存储在数据存储中……
…然后发回一些内容,以便 Javascript 页面可以告诉用户他们可以从现在开始正常使用我们的操作。
还值得注意的是,如果他们甚至在试用 Google 助理版本之前就访问了该网站(即,由于搜索结果或他们从第二张图的第 8 步或第三张图的第 4 步开始的任何事情)并登录,然后我们将在他们第一次通过助手访问我们时获取他们的身份令牌,这将像简单的场景一样工作。
【讨论】:
(我需要回到所有那些旧的身份验证问题并提及这一点。) 感谢您的快速回复!我有一个后端设置来处理身份验证和刷新令牌的存储。我最困惑的是获得额外的范围。使用一个中间件来处理帐户链接和谷歌签名之间的重定向是要走的路吗? 这完全取决于您的意思。我猜你需要一些东西(称之为中间件或其他什么)从网络谷歌登录获取身份验证代码,然后将其交换为身份验证/刷新令牌以存储在你的后端。我正在努力思考如何让我的答案更清楚地解释流程以及需要在哪里完成。 我想澄清一下我并没有试图将任何类型的现有帐户链接到 Google 操作很重要。我希望将当前用户的日历权限授予我的操作。由于 Google 禁用了在帐户链接中使用其 OAuth 端点的能力,我假设他们为用户实现了另一种方式来为操作提供权限? Google 登录链接类型看起来很有希望,但没有提供指定其他范围的选项。我希望这能澄清任何困惑。总的来说,我仍在考虑 OAuth。感谢您的耐心等待。 我明白了,但是一旦您存储了 auth/refresh 令牌 - 您最终将拥有一个必须为用户存储的事实上的“帐户”。正确的? (这就是为什么你也想要验证码,对吗?)以上是关于Google Home 授权代码和使用 Google 帐户进行身份验证的主要内容,如果未能解决你的问题,请参考以下文章
Rails 6 API + React + Google login:登录后如何授权用户访问某些服务器路由?