Vinculação simplificada com o OAuth e o Login do Google

Visão geral

A vinculação simplificada do Login do Google com base em OAuth adiciona o Login do Google com base na vinculação de OAuth. Isso permite uma experiência de vinculação perfeita para os usuários do Google, além de permitir a criação de uma conta, o que permite que o usuário crie uma nova conta no seu serviço usando a Conta do Google.

Para realizar a vinculação de contas com o OAuth e o Login do Google, siga estas etapas gerais:

  1. Primeiro peça para o usuário autorizar o acesso ao perfil do Google.
  2. usar as informações no perfil para verificar se a conta de usuário existe.
  3. Para usuários atuais, vincule as contas.
  4. Se você não encontrar uma correspondência para o usuário do Google no seu sistema de autenticação, valide o token de ID recebido do Google. Em seguida, crie um usuário com base nas informações do perfil contidas no token de ID.
A figura mostra as etapas para um usuário vincular a Conta do Google usando o fluxo de vinculação simplificado. A primeira captura de tela mostra como um usuário pode selecionar seu app para a vinculação. A segunda captura permite que o usuário confirme se ele já tem uma conta no seu serviço. A terceira captura de tela permite que o usuário selecione a Conta do Google que quer vincular. A quarta mostra a confirmação da vinculação da Conta do Google ao app. A quinta mostra uma conta de usuário vinculada no Google app.

Figura 1. Vinculação de contas no smartphone de um usuário com vinculação simplificada

Requisitos para uma vinculação simplificada

Implementar o servidor OAuth

O endpoint de troca de tokens precisa ser compatível com as intents check, create e get. Veja abaixo as etapas do fluxo de vinculação da conta e indica quando as intents diferentes são chamadas:

  1. O usuário tem uma conta no seu sistema de autenticação? O usuário decide se SIM ou NÃO.
    1. SIM : o usuário usa o e-mail associado à Conta do Google para fazer login na sua plataforma? O usuário decide se SIM ou NÃO.
      1. SIM : o usuário tem uma conta correspondente no seu sistema de autenticação? (check intent é chamado para confirmar)
        1. SIM : get intent é chamado, e a conta é vinculada se a intent for retornada com sucesso.
        2. NO : Criar nova conta? O usuário decide se SIM ou NÃO.
          1. SIM : create intent será chamado, e a conta será vinculada se a intent de criação retornar.
          2. NO : o fluxo OAuth da Web é acionado, o usuário é direcionado para seu navegador, e o usuário tem a opção de vincular com um e-mail diferente.
      2. NÃO : o fluxo de OAuth da Web é acionado, o usuário é direcionado para o navegador, e o usuário tem a opção de vincular com um e-mail diferente.
    2. NÃO : o usuário tem uma conta correspondente no seu sistema de autenticação? (check intent é chamado para confirmar)
      1. SIM: get intent é chamado, e a conta é vinculada se a intent for retornada com sucesso.
      2. NO : create intent será chamado, e a conta será vinculada se a intent de criação retornar.

检查现有用户帐号(检查 intent)

在用户同意访问其 Google 个人资料后,Google 会发送一个请求,其中包含 Google 用户身份的签名断言。该断言包含用户的 Google 帐号 ID、姓名和电子邮件地址。为您的项目配置的令牌交换端点会处理该请求。

如果您的身份验证系统中已存在相应的 Google 帐号,则您的令牌交换端点会返回 account_found=true。如果 Google 帐号与现有用户不匹配,那么您的令牌交换端点会返回 account_found=false 的 HTTP 404 Not Found 错误。

请求的格式如下:

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

grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&intent=check&assertion=JWT&scope=SCOPES&client_id=GOOGLE_CLIENT_ID&client_secret=GOOGLE_CLIENT_SECRET

您的令牌交换端点必须能够处理以下参数:

令牌端点参数
intent 对于这些请求,此参数的值为 check
grant_type 要交换的令牌的类型。对于这些请求,此参数的值为 urn:ietf:params:oauth:grant-type:jwt-bearer
assertion 一个 JSON Web 令牌 (JWT),用于提供 Google 用户身份的签名断言。JWT 包含用户的 Google 帐号 ID、姓名和电子邮件地址等信息。
client_id 您分配给 Google 的客户端 ID。
client_secret 您分配给 Google 的客户端密钥。

为了响应 check intent 请求,您的令牌交换端点必须执行以下步骤:

  • 验证并解码 JWT 断言。
  • 检查您的身份验证系统中是否已存在该 Google 帐号。
Valide e decodifique a asserção JWT

Você pode validar e decodificar a declaração JWT usando uma biblioteca de decodificação JWT para o seu idioma . Use as chaves públicas do Google, disponíveis nos formatos JWK ou PEM , para verificar a assinatura do token.

Quando decodificada, a declaração JWT se parece com o seguinte exemplo:

{
  "sub": "1234567890",      // The unique ID of the user's Google Account
  "iss": "https://accounts.google.com",        // The assertion's issuer
  "aud": "123-abc.apps.googleusercontent.com", // Your server's client ID
  "iat": 233366400,         // Unix timestamp of the assertion's creation time
  "exp": 233370000,         // Unix timestamp of the assertion's expiration time
  "name": "Jan Jansen",
  "given_name": "Jan",
  "family_name": "Jansen",
  "email": "jan@gmail.com", // If present, the user's email address
  "email_verified": true,   // true, if Google has verified the email address
  "hd": "example.com",      // If present, the host domain of the user's GSuite email address
                            // If present, a URL to user's profile picture
  "picture": "https://lh3.googleusercontent.com/a-/AOh14GjlTnZKHAeb94A-FmEbwZv7uJD986VOF1mJGb2YYQ",
  "locale": "en_US"         // User's locale, from browser or phone settings
}

Além de verificar a assinatura do token, verifique se o emissor da declaração (campo iss ) é https://accounts.google.com , se o público (campo aud ) é seu ID de cliente atribuído e se o token não expirou ( exp campo).

Usando os campos email , email_verified e hd , você pode determinar se o Google hospeda e se tem autoridade para um endereço de e-mail. Nos casos em que o Google tem autoridade, o usuário é atualmente conhecido como o proprietário legítimo da conta e você pode pular a senha ou outros métodos de desafio. Caso contrário, esses métodos podem ser usados ​​para verificar a conta antes da vinculação.

Casos em que o Google é autoritário:

  • email - email tem um sufixo @gmail.com , esta é uma conta do Gmail.
  • email_verified é true e hd está definido, esta é uma conta do G Suite.

Os usuários podem se registrar em Contas do Google sem usar o Gmail ou o G Suite. Quando o email não contém um sufixo @gmail.com e hd está ausente, o Google não é autoritativo e senha ou outros métodos de desafio são recomendados para verificar o usuário. email_verfied também pode ser verdadeiro, já que o Google verificou inicialmente o usuário quando a conta do Google foi criada; no entanto, a propriedade da conta de e-mail de terceiros pode ter mudado.

检查您的身份验证系统中是否已存在该 Google 帐号

检查是否满足以下任一条件:

  • Google 帐号 ID 可在用户的数据库中找到,可在断言的 sub 字段找到。
  • 断言中的电子邮件地址与您的用户数据库中的用户匹配。

如果其中任一条件为 true,则表示用户已注册。在这种情况下,系统将返回如下所示的响应:

HTTP/1.1 200 Success
Content-Type: application/json;charset=UTF-8

{
  "account_found":"true",
}

如果断言中指定的 Google 帐号 ID 和电子邮件地址都与用户数据库中的用户不匹配,则表示用户尚未注册。在这种情况下,您的令牌交换端点需要使用包含 "account_found": "false" 的 HTTP 404 错误进行响应,如以下示例所示:

HTTP/1.1 404 Not found
Content-Type: application/json;charset=UTF-8

{
  "account_found":"false",
}

处理自动链接(获取 intent)

在用户同意访问其 Google 个人资料后,Google 会发送一个请求,其中包含 Google 用户身份的签名断言。该断言包含用户的 Google 帐号 ID、姓名和电子邮件地址。为您的项目配置的令牌交换端点会处理该请求。

如果您的身份验证系统中已存在相应的 Google 帐号,则您的令牌交换端点会返回用户的令牌。如果 Google 帐号与现有用户不匹配,您的令牌交换端点会返回 linking_error 错误和可选的 login_hint

请求的格式如下:

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

grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&intent=get&assertion=JWT&scope=SCOPES&client_id=GOOGLE_CLIENT_ID&client_secret=GOOGLE_CLIENT_SECRET

您的令牌交换端点必须能够处理以下参数:

令牌端点参数
intent 对于这些请求,此参数的值为 get
grant_type 要交换的令牌的类型。对于这些请求,此参数的值为 urn:ietf:params:oauth:grant-type:jwt-bearer
assertion 一个 JSON Web 令牌 (JWT),用于提供 Google 用户身份的签名断言。JWT 包含用户的 Google 帐号 ID、姓名和电子邮件地址等信息。
scope 可选:您已将 Google 配置为向用户请求的任何范围。
client_id 您分配给 Google 的客户端 ID。
client_secret 您分配给 Google 的客户端密钥。

为了响应 get intent 请求,您的令牌交换端点必须执行以下步骤:

  • 验证并解码 JWT 断言。
  • 检查您的身份验证系统中是否已存在该 Google 帐号。
Valide e decodifique a asserção JWT

Você pode validar e decodificar a declaração JWT usando uma biblioteca de decodificação JWT para o seu idioma . Use as chaves públicas do Google, disponíveis nos formatos JWK ou PEM , para verificar a assinatura do token.

Quando decodificada, a declaração JWT se parece com o seguinte exemplo:

{
  "sub": "1234567890",      // The unique ID of the user's Google Account
  "iss": "https://accounts.google.com",        // The assertion's issuer
  "aud": "123-abc.apps.googleusercontent.com", // Your server's client ID
  "iat": 233366400,         // Unix timestamp of the assertion's creation time
  "exp": 233370000,         // Unix timestamp of the assertion's expiration time
  "name": "Jan Jansen",
  "given_name": "Jan",
  "family_name": "Jansen",
  "email": "jan@gmail.com", // If present, the user's email address
  "email_verified": true,   // true, if Google has verified the email address
  "hd": "example.com",      // If present, the host domain of the user's GSuite email address
                            // If present, a URL to user's profile picture
  "picture": "https://lh3.googleusercontent.com/a-/AOh14GjlTnZKHAeb94A-FmEbwZv7uJD986VOF1mJGb2YYQ",
  "locale": "en_US"         // User's locale, from browser or phone settings
}

Além de verificar a assinatura do token, verifique se o emissor da declaração (campo iss ) é https://accounts.google.com , se o público (campo aud ) é seu ID de cliente atribuído e se o token não expirou ( exp campo).

Usando os campos email , email_verified e hd , você pode determinar se o Google hospeda e se tem autoridade para um endereço de e-mail. Nos casos em que o Google tem autoridade, o usuário é atualmente conhecido como o proprietário legítimo da conta e você pode pular a senha ou outros métodos de desafio. Caso contrário, esses métodos podem ser usados ​​para verificar a conta antes da vinculação.

Casos em que o Google é autoritário:

  • email - email tem um sufixo @gmail.com , esta é uma conta do Gmail.
  • email_verified é true e hd está definido, esta é uma conta do G Suite.

Os usuários podem se registrar em Contas do Google sem usar o Gmail ou o G Suite. Quando o email não contém um sufixo @gmail.com e hd está ausente, o Google não é autoritativo e senha ou outros métodos de desafio são recomendados para verificar o usuário. email_verfied também pode ser verdadeiro, já que o Google verificou inicialmente o usuário quando a conta do Google foi criada; no entanto, a propriedade da conta de e-mail de terceiros pode ter mudado.

检查您的身份验证系统中是否已存在该 Google 帐号

检查是否满足以下任一条件:

  • Google 帐号 ID 可在用户的数据库中找到,可在断言的 sub 字段找到。
  • 断言中的电子邮件地址与您的用户数据库中的用户匹配。

如果找到了用户的帐号,请发出访问令牌,并在 HTTPS 响应的正文中以 JSON 对象形式返回值,如以下示例所示:

{
  "token_type": "Bearer",
  "access_token": "ACCESS_TOKEN",

  "expires_in": SECONDS_TO_EXPIRATION
}

在某些情况下,基于 ID 令牌的帐号关联可能会为用户失败。如果出现任何此类情况,您的令牌交换端点都需要使用返回 error=linking_error 的 HTTP 401 错误进行响应,如以下示例所示:

HTTP/1.1 401 Unauthorized
Content-Type: application/json;charset=UTF-8

{
  "error":"linking_error",
  "login_hint":"foo@bar.com"
}

Google 收到包含 linking_error 的 401 错误响应后,会将用户作为授权参数 login_hint 发送到您的授权端点。用户在浏览器中使用 OAuth 关联流程完成帐号关联。

通过 Google 登录功能创建帐号(创建 intent)

当用户需要在您的服务上创建帐号时,Google 会向您的令牌交换端点发出请求,并指定 intent=create

请求的格式如下:

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

response_type=token&grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&scope=SCOPES&intent=create&assertion=JWT&client_id=GOOGLE_CLIENT_ID&client_secret=GOOGLE_CLIENT_SECRET

您的令牌交换端点必须能够处理以下参数:

令牌端点参数
intent 对于这些请求,此参数的值为 create
grant_type 要交换的令牌的类型。对于这些请求,此参数的值为 urn:ietf:params:oauth:grant-type:jwt-bearer
assertion 一个 JSON Web 令牌 (JWT),用于提供 Google 用户身份的签名断言。JWT 包含用户的 Google 帐号 ID、姓名和电子邮件地址等信息。
client_id 您分配给 Google 的客户端 ID。
client_secret 您分配给 Google 的客户端密钥。

assertion 参数中的 JWT 包含用户的 Google 帐号 ID、名称和电子邮件地址,您可以使用这些信息在服务中创建新帐号。

为了响应 create intent 请求,您的令牌交换端点必须执行以下步骤:

  • 验证并解码 JWT 断言。
  • 验证用户信息并创建新帐号。
Valide e decodifique a asserção JWT

Você pode validar e decodificar a declaração JWT usando uma biblioteca de decodificação JWT para o seu idioma . Use as chaves públicas do Google, disponíveis nos formatos JWK ou PEM , para verificar a assinatura do token.

Quando decodificada, a declaração JWT se parece com o seguinte exemplo:

{
  "sub": "1234567890",      // The unique ID of the user's Google Account
  "iss": "https://accounts.google.com",        // The assertion's issuer
  "aud": "123-abc.apps.googleusercontent.com", // Your server's client ID
  "iat": 233366400,         // Unix timestamp of the assertion's creation time
  "exp": 233370000,         // Unix timestamp of the assertion's expiration time
  "name": "Jan Jansen",
  "given_name": "Jan",
  "family_name": "Jansen",
  "email": "jan@gmail.com", // If present, the user's email address
  "email_verified": true,   // true, if Google has verified the email address
  "hd": "example.com",      // If present, the host domain of the user's GSuite email address
                            // If present, a URL to user's profile picture
  "picture": "https://lh3.googleusercontent.com/a-/AOh14GjlTnZKHAeb94A-FmEbwZv7uJD986VOF1mJGb2YYQ",
  "locale": "en_US"         // User's locale, from browser or phone settings
}

Além de verificar a assinatura do token, verifique se o emissor da declaração (campo iss ) é https://accounts.google.com , se o público (campo aud ) é seu ID de cliente atribuído e se o token não expirou ( exp campo).

Usando os campos email , email_verified e hd , você pode determinar se o Google hospeda e se tem autoridade para um endereço de e-mail. Nos casos em que o Google tem autoridade, o usuário é atualmente conhecido como o proprietário legítimo da conta e você pode pular a senha ou outros métodos de desafio. Caso contrário, esses métodos podem ser usados ​​para verificar a conta antes da vinculação.

Casos em que o Google é autoritário:

  • email - email tem um sufixo @gmail.com , esta é uma conta do Gmail.
  • email_verified é true e hd está definido, esta é uma conta do G Suite.

Os usuários podem se registrar em Contas do Google sem usar o Gmail ou o G Suite. Quando o email não contém um sufixo @gmail.com e hd está ausente, o Google não é autoritativo e senha ou outros métodos de desafio são recomendados para verificar o usuário. email_verfied também pode ser verdadeiro, já que o Google verificou inicialmente o usuário quando a conta do Google foi criada; no entanto, a propriedade da conta de e-mail de terceiros pode ter mudado.

验证用户信息并创建新帐号

检查是否满足以下任一条件:

  • Google 帐号 ID 可在用户的数据库中找到,可在断言的 sub 字段找到。
  • 断言中的电子邮件地址与您的用户数据库中的用户匹配。

如果任一条件为 true,请提示用户将其现有帐号与其 Google 帐号相关联。为此,请对请求进行响应,并提供指定 error=linking_error 并将用户的电子邮件地址作为 login_hint 的 HTTP 401 错误。以下是一个示例响应:

HTTP/1.1 401 Unauthorized
Content-Type: application/json;charset=UTF-8

{
  "error":"linking_error",
  "login_hint":"foo@bar.com"
}

Google 收到包含 linking_error 的 401 错误响应后,会将用户作为授权参数 login_hint 发送到您的授权端点。用户在浏览器中使用 OAuth 关联流程完成帐号关联。

如果两个条件都不满足,请使用 JWT 中提供的信息创建新的用户帐号。新帐号通常不会设置密码。建议您将 Google 登录功能添加到其他平台,以便用户能够在应用界面使用 Google 帐号登录。或者,您也可以通过电子邮件向用户发送一个启动密码恢复流程的链接,以便用户设置密码以在其他平台上登录。

创建完成后,发出访问令牌 ,并在 HTTPS 响应的正文中以 JSON 对象形式返回值,如以下示例所示:

{
  "token_type": "Bearer",
  "access_token": "ACCESS_TOKEN",

  "expires_in": SECONDS_TO_EXPIRATION
}

Ver o ID do cliente da API do Google

Será necessário fornecer seu ID do cliente da API do Google durante o processo de registro da vinculação de contas.

Para conseguir o ID do cliente da API usando o projeto criado durante a conclusão das etapas da vinculação do OAuth. Para isso, siga estas etapas:

  1. Abra a página Credenciais do Console de APIs do Google.
  2. Crie ou selecione um projeto de APIs do Google.

    Se o projeto não tiver um ID do cliente para o tipo de aplicativo da Web, clique em Criar credenciais > ID do cliente OAuth para criar um. Inclua o domínio do seu site na caixa Origens JavaScript autorizadas. Ao realizar testes ou desenvolvimento locais, é necessário adicionar http://localhost e http://localhost:<port_number> ao campo Origens JavaScript autorizadas.

Como validar a implementação

Você pode validar a sua implementação, utilizando o Parque OAuth 2.0 ferramenta.

Na ferramenta, execute as seguintes etapas:

  1. Clique em Configuração para abrir a janela de configuração do OAuth 2.0.
  2. No campo de fluxo OAuth, selecione do lado do cliente.
  3. No campo OAuth Endpoints, selecione Personalizado.
  4. Especifique seu ponto de extremidade OAuth 2.0 e o ID do cliente que você atribuiu ao Google nos campos correspondentes.
  5. Na secção Passo 1, não selecione quaisquer âmbitos do Google. Em vez disso, deixe este campo em branco ou digite um escopo válido para o seu servidor (ou uma string arbitrária se você não usar escopos OAuth). Quando estiver pronto, clique em Autorizar APIs.
  6. Nas secções Passo 2 e Passo 3, ir por meio do fluxo OAuth 2.0 e verificar que cada passo funciona como pretendido.

Você pode validar sua implementação usando a Conta do Google Linking Demonstração ferramenta.

Na ferramenta, execute as seguintes etapas:

  1. Clique no sinal-in com o botão Google.
  2. Escolha a conta que deseja vincular.
  3. Digite o ID do serviço.
  4. Opcionalmente, insira um ou mais escopos para os quais você solicitará acesso.
  5. Clique em Iniciar demonstração.
  6. Quando solicitado, confirme se você pode consentir e negar a solicitação de vinculação.
  7. Confirme que você foi redirecionado para sua plataforma.