Google 主页授权码和使用 Google 帐户的身份验证
Google Home Authorization Code and Authentication with Google Account
我目前正在尝试使用 Google 主页操作对 Google 帐户进行身份验证,并从凭据中检索授权码。我不想要访问令牌,而是授权码。
我查看了 并发现 Google 更新了他们的政策,不再允许他们自己的 OAuth 端点用于帐户链接授权代码流:
When implementing account linking using OAuth, you must own your OAuth endpoint
也就是说,
- 用我的操作和必要的范围验证现有 Google 用户的正确方法是什么? (我需要日历访问权限)
- 是否可以在不必创建我自己的 OAuth2.0 端点的情况下进行此身份验证?
- 从这个流程中,是否可以提取授权码?
当前通过 Google 帐户验证用户身份的方法是使用 Google Sign-In for Assistant。一旦他们登录到您的 Action,您将获得一个 ID 令牌,您可以对其进行解码以获取他们的 Google ID,您可以使用该 ID 在您的数据存储中查找他们的帐户以获取他们的 access/refresh 令牌.
由于您需要额外的范围,如果用户登录到助手但尚未将范围附加到他们的帐户,您会将他们重定向到基于 Web 的登录页面,他们可以在其中使用 Google 使用您需要的范围登录。在这种情况下,当他们登录并授权通过网络访问时,您将获得授权代码,您需要用该代码交换授权令牌和刷新令牌并存储它们。
您不需要为此创建自己的 OAuth 端点,但您需要做一些额外的工作以确保它们被重定向到您的网站以在必要时进行授权。
当他们登录并授权给您时,您只会获得授权码一次。您需要将其交换为身份验证和刷新令牌,然后存储这些令牌。
更新 以更好地解释事情。
查看架构,我们发现它有几个组件。我们将在处理流程时详细介绍每一项:
您有某种数据存储,您将在其中存储用户的 Auth Token 和 Refresh Token。我假设您使用 Google 的用户 ID 作为该数据存储的索引。
在这种情况下,"Google User ID" 是指 Google 分配给每个帐户的唯一数字标识符。这通常表示为字符串,尽管只有数字,因为它通常比大多数数字类型长得多。在 ID 令牌中,这是 "sub" 声明。
理论上,您可以使用 ID 令牌声明中提供的其他标识符,例如他们的电子邮件地址。遗憾的是,并非所有这些字段都保证可用 - 只有 "sub" 是有保证的。
您有一个 Web 服务器,其中包含一些对我们而言很重要的 URL:
- 您的操作实现的网络挂钩。
- 一个 login/auth 页。
- 登录页面上的 javascript 将向您发送授权码的端点。
Google 智能助理,可能 运行 在 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 交谈怎么办?并且从未授权我们访问他们的 Google 服务,所以我们没有他们的令牌?该流程看起来更像这样:
- Assistant 向 Action webhook 发送 Intent 和可能的参数。这将是第一条消息,因此我们的欢迎意图被触发。没有身份令牌。
- webhook 发现没有身份令牌,因此发回一条消息请求“登录”辅助函数。由于您的项目配置为使用 Google 登录,如果用户可以向您提供他们的个人资料信息,助手将提示用户。
- 如果他们同意,您将收到另一个回复,说他们已经登录并包括身份令牌,我们对其进行解码和验证并获取他们的用户 ID。 (如果他们拒绝,我们会收到回复说失败。你如何处理这是另一回事。我假设他们说是。)
- 使用用户 ID…
- ...我们尝试从数据存储中获取 Auth Token 和 Refresh Token。但他们还没有授权我们。我们已经验证了他们,但是没有授权...
- ...所以我们发回一条消息说他们需要访问我们的网站以授权我们访问他们的 Google 服务。我们可能会要求他们切换到移动设备来执行此部分,甚至在登录页面中包含一个 link。
- 他们会在有屏幕的设备上跟随link。
- 我们将发回登录页面,其中包含 link 以使用 Google 登录。我们已将此按钮配置为还要求我们访问其服务所需的其他范围,以及在“离线”时代表他们访问服务的权限。
- 他们将通过 Google 登录舞蹈、OAuth 范围屏幕,并有望授予我们想要的所有权限。 (同样,如果他们不这样做,我会忽略会发生什么。)我忽略了那支舞蹈的样子,因为它不涉及我们。假设一切顺利,Google 给他们一个授权码,登录页面上的 javascript 发送给我们。
- 我们调用Google的OAuth服务器来验证Auth Code并用它来获取Auth Token和Refresh Token…
- ...然后我们将其存储在数据存储中...
- …然后发回一些东西让Javascript页面可以告诉用户从现在开始他们可以正常使用我们的Action。
他们现在可以做到,而且它的行为与之前的简单场景中一样。
这看起来很复杂,但事实证明在某些情况下我们可以删除一些步骤。如果 Google 云项目是您用于操作和基于网络的 Google 登录的同一个项目,那么一旦他们在网络上授权该项目,所有调用您的实现将包括身份令牌。这让我们删除上面的步骤 2-6,所以事情看起来更像这样:
- Assistant 向 Action webhook 发送 Intent 和可能的参数。这将是第一条消息,因此我们的欢迎意图被触发。没有身份令牌。
- webhook 发现没有身份令牌,所以我们发回一条消息说他们需要访问我们的网站以授权我们访问他们的 Google 服务。我们可能会要求他们切换到移动设备来执行此部分,甚至在登录页面中包含 link。 (这是上面折叠的第 2 步和第 6 步。)
- 他们会在有屏幕的设备上跟随link。
- 我们将发回登录页面,其中包含 link 以使用 Google 登录。我们已将此按钮配置为还要求我们访问其服务所需的其他范围,以及在“离线”时代表他们访问服务的权限。
- 他们将通过 Google 登录舞蹈、OAuth 范围屏幕,并有望授予我们想要的所有权限。 (同样,如果他们不这样做,我会忽略会发生什么。)我忽略了那支舞蹈的样子,因为它不涉及我们。假设一切顺利,Google 给他们一个授权码,登录页面上的 javascript 发送给我们。
- 我们调用Google的OAuth服务器来验证Auth Code并用它来获取Auth Token和Refresh Token…
- ...然后我们将其存储在数据存储中...
- …然后发回一些东西让Javascript页面可以告诉用户从现在开始他们可以正常使用我们的Action。
同样值得注意的是,如果他们甚至在试用助手版本之前就访问了该网站(即 - 因为搜索结果或他们从第二张图的第 8 步或第三张图的第 4 步开始的任何原因)并且登录,然后我们将在他们第一次通过助手访问我们时获得他们的身份令牌,这将像简单的场景一样工作。
我目前正在尝试使用 Google 主页操作对 Google 帐户进行身份验证,并从凭据中检索授权码。我不想要访问令牌,而是授权码。
我查看了
When implementing account linking using OAuth, you must own your OAuth endpoint
也就是说,
- 用我的操作和必要的范围验证现有 Google 用户的正确方法是什么? (我需要日历访问权限)
- 是否可以在不必创建我自己的 OAuth2.0 端点的情况下进行此身份验证?
- 从这个流程中,是否可以提取授权码?
当前通过 Google 帐户验证用户身份的方法是使用 Google Sign-In for Assistant。一旦他们登录到您的 Action,您将获得一个 ID 令牌,您可以对其进行解码以获取他们的 Google ID,您可以使用该 ID 在您的数据存储中查找他们的帐户以获取他们的 access/refresh 令牌.
由于您需要额外的范围,如果用户登录到助手但尚未将范围附加到他们的帐户,您会将他们重定向到基于 Web 的登录页面,他们可以在其中使用 Google 使用您需要的范围登录。在这种情况下,当他们登录并授权通过网络访问时,您将获得授权代码,您需要用该代码交换授权令牌和刷新令牌并存储它们。
您不需要为此创建自己的 OAuth 端点,但您需要做一些额外的工作以确保它们被重定向到您的网站以在必要时进行授权。
当他们登录并授权给您时,您只会获得授权码一次。您需要将其交换为身份验证和刷新令牌,然后存储这些令牌。
更新 以更好地解释事情。
查看架构,我们发现它有几个组件。我们将在处理流程时详细介绍每一项:
您有某种数据存储,您将在其中存储用户的 Auth Token 和 Refresh Token。我假设您使用 Google 的用户 ID 作为该数据存储的索引。
在这种情况下,"Google User ID" 是指 Google 分配给每个帐户的唯一数字标识符。这通常表示为字符串,尽管只有数字,因为它通常比大多数数字类型长得多。在 ID 令牌中,这是 "sub" 声明。
理论上,您可以使用 ID 令牌声明中提供的其他标识符,例如他们的电子邮件地址。遗憾的是,并非所有这些字段都保证可用 - 只有 "sub" 是有保证的。
您有一个 Web 服务器,其中包含一些对我们而言很重要的 URL:
- 您的操作实现的网络挂钩。
- 一个 login/auth 页。
- 登录页面上的 javascript 将向您发送授权码的端点。
Google 智能助理,可能 运行 在 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 交谈怎么办?并且从未授权我们访问他们的 Google 服务,所以我们没有他们的令牌?该流程看起来更像这样:
- Assistant 向 Action webhook 发送 Intent 和可能的参数。这将是第一条消息,因此我们的欢迎意图被触发。没有身份令牌。
- webhook 发现没有身份令牌,因此发回一条消息请求“登录”辅助函数。由于您的项目配置为使用 Google 登录,如果用户可以向您提供他们的个人资料信息,助手将提示用户。
- 如果他们同意,您将收到另一个回复,说他们已经登录并包括身份令牌,我们对其进行解码和验证并获取他们的用户 ID。 (如果他们拒绝,我们会收到回复说失败。你如何处理这是另一回事。我假设他们说是。)
- 使用用户 ID…
- ...我们尝试从数据存储中获取 Auth Token 和 Refresh Token。但他们还没有授权我们。我们已经验证了他们,但是没有授权...
- ...所以我们发回一条消息说他们需要访问我们的网站以授权我们访问他们的 Google 服务。我们可能会要求他们切换到移动设备来执行此部分,甚至在登录页面中包含一个 link。
- 他们会在有屏幕的设备上跟随link。
- 我们将发回登录页面,其中包含 link 以使用 Google 登录。我们已将此按钮配置为还要求我们访问其服务所需的其他范围,以及在“离线”时代表他们访问服务的权限。
- 他们将通过 Google 登录舞蹈、OAuth 范围屏幕,并有望授予我们想要的所有权限。 (同样,如果他们不这样做,我会忽略会发生什么。)我忽略了那支舞蹈的样子,因为它不涉及我们。假设一切顺利,Google 给他们一个授权码,登录页面上的 javascript 发送给我们。
- 我们调用Google的OAuth服务器来验证Auth Code并用它来获取Auth Token和Refresh Token…
- ...然后我们将其存储在数据存储中...
- …然后发回一些东西让Javascript页面可以告诉用户从现在开始他们可以正常使用我们的Action。
他们现在可以做到,而且它的行为与之前的简单场景中一样。
这看起来很复杂,但事实证明在某些情况下我们可以删除一些步骤。如果 Google 云项目是您用于操作和基于网络的 Google 登录的同一个项目,那么一旦他们在网络上授权该项目,所有调用您的实现将包括身份令牌。这让我们删除上面的步骤 2-6,所以事情看起来更像这样:
- Assistant 向 Action webhook 发送 Intent 和可能的参数。这将是第一条消息,因此我们的欢迎意图被触发。没有身份令牌。
- webhook 发现没有身份令牌,所以我们发回一条消息说他们需要访问我们的网站以授权我们访问他们的 Google 服务。我们可能会要求他们切换到移动设备来执行此部分,甚至在登录页面中包含 link。 (这是上面折叠的第 2 步和第 6 步。)
- 他们会在有屏幕的设备上跟随link。
- 我们将发回登录页面,其中包含 link 以使用 Google 登录。我们已将此按钮配置为还要求我们访问其服务所需的其他范围,以及在“离线”时代表他们访问服务的权限。
- 他们将通过 Google 登录舞蹈、OAuth 范围屏幕,并有望授予我们想要的所有权限。 (同样,如果他们不这样做,我会忽略会发生什么。)我忽略了那支舞蹈的样子,因为它不涉及我们。假设一切顺利,Google 给他们一个授权码,登录页面上的 javascript 发送给我们。
- 我们调用Google的OAuth服务器来验证Auth Code并用它来获取Auth Token和Refresh Token…
- ...然后我们将其存储在数据存储中...
- …然后发回一些东西让Javascript页面可以告诉用户从现在开始他们可以正常使用我们的Action。
同样值得注意的是,如果他们甚至在试用助手版本之前就访问了该网站(即 - 因为搜索结果或他们从第二张图的第 8 步或第三张图的第 4 步开始的任何原因)并且登录,然后我们将在他们第一次通过助手访问我们时获得他们的身份令牌,这将像简单的场景一样工作。