Vinculação de contas com o OAuth

O tipo de vinculação OAuth é compatível com dois fluxos do OAuth 2.0 padrão do setor: os fluxos de código implícito e de autorização.

In the implicit code flow, Google opens your authorization endpoint in the user's browser. After successful sign in, you return a long-lived access token to Google. This access token is now included in every request sent from the Assistant to your Action.

In the authorization code flow, you need two endpoints:

  • The authorization endpoint, which is responsible for presenting the sign-in UI to your users that aren't already signed in and recording consent to the requested access in the form of a short-lived authorization code.
  • The token exchange endpoint, which is responsible for two types of exchanges:
    1. Exchanges an authorization code for a long-lived refresh token and a short-lived access token. This exchange happens when the user goes through the account linking flow.
    2. Exchanges a long-lived refresh token for a short-lived access token. This exchange happens when Google needs a new access token because the one it had expired.

Although the implicit code flow is simpler to implement, Google recommends that access tokens issued using the implicit flow never expire, because using token expiration with the implicit flow forces the user to link their account again. If you need token expiration for security reasons, you should strongly consider using the auth code flow instead.

Implementar a vinculação de conta OAuth

Configurar o projeto

Para configurar seu projeto para usar a vinculação OAuth, siga estas etapas:

  1. Abra o Console do Actions e selecione o projeto que você quer usar.
  2. Clique na guia Desenvolver e escolha Vinculação de contas.
  3. Ative a chave ao lado de Vinculação de contas.
  4. Na seção Criação de conta, selecione Não, quero permitir apenas a criação de contas no meu site.
  5. Em Tipo de vinculação, selecione OAuth e Código de autorização.

  6. Em Informações do cliente:

    • Atribua um valor ao ID do cliente emitido pelas suas ações para o Google para identificar solicitações do Google.
    • Anote o valor do ID do cliente emitido pelo Google para suas Ações.
    • Insira os URLs dos endpoints de autorização e de troca de tokens.
  1. Clique em Salvar.

Implementar o servidor OAuth

授权代码流程的 OAuth 2.0 服务器实现包含两个端点,您的服务通过 HTTPS 提供这些端点。第一个端点是授权端点,负责就数据访问征求用户意见或征求用户意见。授权端点会向尚未登录的用户呈现登录界面,并记录对于请求的访问权限。第二个端点是令牌交换端点,该端点用于获取加密字符串(称为令牌),用于授权 Action 用户访问您的服务。

当您的 Action 需要调用服务的某个 API 时,Google 会同时使用这些端点从用户处获取权限,以代表他们调用这些 API。

由 Google 发起的 OAuth 2.0 授权代码流程会话具有以下流程:

  1. Google 会在用户的浏览器中打开您的授权端点。如果针对 Action 的流程在纯语音设备上开始,Google 会将执行传输到手机。
  2. 用户登录(如果尚未登录),并向 Google 授予使用您的 API 访问其数据的权限(如果他们尚未授予权限)。

  3. 您的服务会创建授权代码,并将用户的浏览器重定向回 Google,并将授权代码附加到请求,从而将其返回给 Google。

  4. Google 会将授权代码发送到您的令牌交换端点,该端点会验证代码的真实性并返回访问令牌刷新令牌。访问令牌是短期有效的令牌,您的服务可接受该令牌作为访问 API 的凭据。刷新令牌是一个长期令牌,Google 可以存储该令牌,并在令牌过期时用它来获取新的访问令牌。

  5. 用户完成帐号关联流程后,从 Google 助理发送到您的执行方式网络钩子的每个后续请求都会包含访问令牌。

处理授权请求

当您的 Action 需要通过 OAuth 2.0 授权代码流程执行帐号关联时,Google 会通过包含以下参数的请求将用户发送到您的授权端点:

授权端点参数
client_id 您向 Google 注册的 Google 客户端 ID。
redirect_uri 您要将该请求的响应发送到的网址。
state 在重定向 URI 中原封不动地传回 Google 的簿记值。
scope 可选:一组用空格分隔的范围字符串,用于指定 Google 请求授权的数据。
response_type 字符串 code

例如,如果您的授权端点位于 https://myservice.example.com/auth,请求可能如下所示:

GET https://myservice.example.com/auth?client_id=GOOGLE_CLIENT_ID&redirect_uri=REDIRECT_URI&state=STATE_STRING&scope=REQUESTED_SCOPES&response_type=code

为了让授权端点能够处理登录请求,请执行以下步骤:

  1. 验证 client_id 与您向 Google 注册的 Google 客户端 ID 是否匹配,以及 redirect_uri 是否与 Google 为您的服务提供的重定向网址匹配。这些检查对于防止授予对意外或配置错误的客户端应用的访问权限非常重要。

    如果您支持多个 OAuth 2.0 流程,另请确认 response_typecode

  2. 检查用户是否登录了您的服务。如果用户没有登录,请完成服务的登录或注册流程。

  3. 生成 Google 用于访问您的 API 的授权代码。授权代码可以是任何字符串值,但它必须唯一地表示用户、令牌的客户端和代码的到期时间,并且必须不可猜测。您通常会签发大约 10 分钟后失效的授权代码。

  4. 确认 redirect_uri 参数指定的网址采用以下格式:

    https://oauth-redirect.googleusercontent.com/r/YOUR_PROJECT_ID
    YOUR_PROJECT_ID 是在 Actions 控制台的 Project settings 页面上找到的 ID。

  5. 将用户浏览器重定向到 redirect_uri 参数指定的网址。通过附加 codestate 参数进行重定向时,请添加您刚刚生成的授权代码以及未经修改的原始状态值。以下是生成的网址的示例:

    https://oauth-redirect.googleusercontent.com/r/YOUR_PROJECT_ID?code=AUTHORIZATION_CODE&state=STATE_STRING

处理令牌交换请求

您的服务的令牌交换端点负责两种令牌交换:

  • 将授权代码换成访问令牌和刷新令牌
  • 将刷新令牌交换为访问令牌

令牌交换请求包含以下参数:

令牌交换端点参数
client_id 将请求来源标识为 Google 的字符串。该字符串必须在您的系统中注册为 Google 的唯一标识符。
client_secret 您为服务向 Google 注册的密钥字符串。
grant_type 要交换的令牌的类型。可以选择 authorization_coderefresh_token
code 当为 grant_type=authorization_code 时,Google 从您的登录端点或令牌交换端点收到的代码。
redirect_uri 如果此参数为 grant_type=authorization_code,则此参数是在初始授权请求中使用的网址。
refresh_token 如果为 grant_type=refresh_token,则表示 Google 从令牌交换端点收到的刷新令牌。
将授权代码换成访问令牌和刷新令牌

用户登录后,您的授权端点向 Google 返回短期有效的授权代码后,Google 会向令牌交换端点发送请求,以用授权代码换取访问令牌和刷新令牌。

对于这些请求,grant_type 的值为 authorization_codecode 的值为您之前授予 Google 的授权代码的值。以下示例展示了用授权代码交换访问令牌和刷新令牌的请求:

POST /token HTTP/1.1
Host: oauth2.example.com
Content-Type: application/x-www-form-urlencoded

client_id=GOOGLE_CLIENT_ID&client_secret=GOOGLE_CLIENT_SECRET&grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=REDIRECT_URI

为了用访问令牌和刷新令牌交换授权代码,令牌交换端点会响应执行以下步骤的 POST 请求:

  1. 验证 client_id 是否将请求来源标识为已获授权的来源,以及 client_secret 是否与预期值匹配。
  2. 请验证以下内容:
    • 授权代码有效且未过期,并且请求中指定的客户端 ID 与授权代码关联的客户端 ID 一致。
    • redirect_uri 参数指定的网址与初始授权请求中使用的值相同。
  3. 如果您无法验证上述所有条件,则返回正文为 {"error": "invalid_grant"} 的 HTTP 400 Bad Request 错误。
  4. 否则,使用授权代码中的用户 ID 生成刷新令牌和访问令牌。这些令牌可以是任何字符串值,但必须唯一地代表用户和令牌所面向的客户端,并且不得被猜到。对于访问令牌,还要记录令牌的到期时间(通常在令牌颁发一小时后)。刷新令牌不会过期。
  5. 在 HTTPS 响应的正文中返回以下 JSON 对象:
    {
    "token_type": "Bearer",
    "access_token": "ACCESS_TOKEN",
    "refresh_token": "REFRESH_TOKEN",
    "expires_in": SECONDS_TO_EXPIRATION
    }
    

Google 会存储用户的访问令牌和刷新令牌,并记录访问令牌的失效时间。访问令牌到期后,Google 会使用刷新令牌从您的令牌交换端点获取新的访问令牌。

将刷新令牌交换为访问令牌

访问令牌到期后,Google 会向令牌交换端点发送请求,以用刷新令牌换取新的访问令牌。

对于这些请求,grant_type 的值为 refresh_tokenrefresh_token 的值为您之前授予 Google 的刷新令牌的值。以下示例展示了将刷新令牌交换为访问令牌的请求:

POST /token HTTP/1.1
Host: oauth2.example.com
Content-Type: application/x-www-form-urlencoded

client_id=GOOGLE_CLIENT_ID&client_secret=GOOGLE_CLIENT_SECRET&grant_type=refresh_token&refresh_token=REFRESH_TOKEN

为了用刷新令牌换取访问令牌,令牌交换端点会响应执行以下步骤的 POST 请求:

  1. 验证 client_id 是否将请求来源标识为 Google,以及 client_secret 是否与预期值匹配。
  2. 验证刷新令牌是否有效,以及请求中指定的客户端 ID 是否与与刷新令牌关联的客户端 ID 匹配。
  3. 如果您无法验证上述所有条件,则返回正文为 {"error": "invalid_grant"} 的 HTTP 400 Bad Request 错误。
  4. 否则,请使用刷新令牌中的用户 ID 生成访问令牌。这些令牌可以是任何字符串值,但必须唯一地代表用户和令牌所面向的客户端,并且不得被猜到。对于访问令牌,还要记录令牌的到期时间(通常在令牌颁发一小时后)。
  5. 在 HTTPS 响应的正文中返回以下 JSON 对象:
    {
    "token_type": "Bearer",
    "access_token": "ACCESS_TOKEN",
    "expires_in": SECONDS_TO_EXPIRATION
    }

Projetar a interface do usuário de voz para o fluxo de autenticação

Conferir se o usuário foi verificado e iniciar o fluxo de vinculação da conta

  1. Abra seu projeto do Actions Builder no Actions Console.
  2. Crie um novo cenário para começar a vinculação da conta na sua Ação:
    1. Clique em Cenas.
    2. Clique no ícone add (+) para adicionar uma nova cena.
  3. No cenário recém-criado, clique no ícone de adição para Condições.
  4. Adicione uma condição que verifica se o usuário associado à conversa é um usuário verificado. Se a verificação falhar, a Ação não poderá fazer a vinculação da conta durante a conversa e vai voltar a fornecer acesso a recursos que não exijam a vinculação de conta.
    1. No campo Enter new expression em Condição, insira a seguinte lógica: user.verificationStatus != "VERIFIED"
    2. Em Transição, selecione uma cena que não exija vinculação de conta ou uma cena que seja o ponto de entrada para a funcionalidade exclusiva para convidados.

  1. Clique no ícone de adição para Condições.
  2. Adicione uma condição para acionar um fluxo de vinculação de conta se o usuário não tiver uma identidade associada.
    1. No campo Enter new expression em Condição, insira a seguinte lógica: user.verificationStatus == "VERIFIED"
    2. Em Transição, selecione a cena do sistema Vinculação de contas.
    3. Clique em Salvar.

Depois de salvar, uma nova cena do sistema de vinculação de contas chamada <SceneName>_AccountLinking será adicionada ao projeto.

Personalizar o cenário de vinculação da conta

  1. Em Scenes, selecione a cena do sistema de vinculação de contas.
  2. Clique em Enviar solicitação e adicione uma frase curta para descrever ao usuário por que a ação precisa acessar a identidade dele (por exemplo, "Para salvar suas preferências").
  3. Clique em Salvar.

  1. Em Condições, clique em Se o usuário concluir a vinculação da conta.
  2. Configure como o fluxo deve proceder se o usuário concordar em vincular a conta. Por exemplo, chame o webhook para processar qualquer lógica de negócios personalizada necessária e fazer a transição de volta para a cena de origem.
  3. Clique em Salvar.

  1. Em Condições, clique em Se o usuário cancelar ou dispensar a vinculação da conta.
  2. Configure como o fluxo deve proceder se o usuário não concordar em vincular a conta. Por exemplo, envie uma mensagem de confirmação e redirecione para cenas que fornecem funcionalidades que não exigem vinculação de conta.
  3. Clique em Salvar.

  1. Em Condições, clique em Se ocorrer um erro de sistema ou rede.
  2. Configure como o fluxo vai proceder se não for possível concluir o fluxo de vinculação da conta devido a erros no sistema ou na rede. Por exemplo, envie uma mensagem de confirmação e redirecione para cenas que fornecem funcionalidades que não exigem vinculação de conta.
  3. Clique em Salvar.

Processar solicitações de acesso a dados

Se a solicitação do Google Assistente contiver um token de acesso, primeiro verifique se o token de acesso é válido (e não expirou) e, em seguida, recupere a conta de usuário associada do seu banco de dados.