目前通过用户的 Google 帐户对用户进行身份验证的方法是使用 Google Sign-In for Assistant。一旦他们登录到您的 Action,您将获得一个 id 令牌,您可以对其进行解码以获取他们的 Google ID,您可以使用它在您的数据存储区中查找他们的帐户以获取他们的访问/刷新令牌。
由于您需要其他范围,如果用户登录到 Google 助理并且尚未将范围附加到他们的帐户,您会将他们重定向到基于 Web 的登录页面,他们可以在其中使用 Google Sign 登录 -在您需要的范围内。在这种情况下,当他们通过网络登录并授权访问时,您将获得验证码,您将需要该验证码来交换验证令牌和刷新令牌并存储这些。
您不需要为此创建自己的 OAuth 端点,但您需要做一些额外的工作以确保它们被重定向到您的网站以在必要时进行授权。
当他们登录并授权您时,您只会获得一次的授权码。您需要将其交换为身份验证和刷新令牌,然后存储这些令牌。
更新以更好地解释事情。
查看架构,我们看到它有几个组件。在处理流程时,我们将详细介绍其中的每一项:
-
您有某种数据存储,您将在其中存储用户的 Auth Token 和 Refresh Token。我将假设您使用 Google 的用户 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 步开始的任何事情)并登录,然后我们将在他们第一次通过助手访问我们时获取他们的身份令牌,这将像简单的场景一样工作。