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.

Verificar se já existe uma conta de usuário (verificar intent)

Depois que o usuário autoriza o acesso ao perfil, o Google envia uma solicitação com uma declaração assinada da identidade do usuário. A declaração contém informações que incluem o ID, o nome e o endereço de e-mail da Conta do Google do usuário. O endpoint de troca de token configurado para seu projeto processa essa solicitação.

Se a Conta do Google correspondente já estiver presente no sistema de autenticação, o endpoint de troca de token responderá com account_found=true. Se a Conta do Google não corresponder a um usuário existente, o endpoint de troca de token retornará um erro HTTP 404 Not Found com account_found=false.

A solicitação tem o seguinte formato:

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

O endpoint de troca de token precisa processar os seguintes parâmetros:

Parâmetros de endpoint de token
intent Para essas solicitações, o valor desse parâmetro é check.
grant_type O tipo de token que está sendo trocado. Para essas solicitações, o valor deste parâmetro é urn:ietf:params:oauth:grant-type:jwt-bearer.
assertion Um Token da Web JSON (JWT) que fornece uma declaração assinada da identidade do usuário do Google. O JWT contém informações que incluem o ID, o nome e o endereço de e-mail da Conta do Google do usuário.
client_id ID do cliente atribuído ao Google
client_secret A chave secreta do cliente que você atribuiu ao Google

Para responder às solicitações de intent check, seu endpoint de troca de token precisa executar as seguintes etapas:

  • Validar e decodificar a declaração JWT.
  • Verifique se a Conta do Google já está presente no sistema de autenticação.
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.

Verificar se a Conta do Google já está presente no sistema de autenticação

Verifique se uma destas condições é verdadeira:

  • O ID da Conta do Google, encontrado no campo sub da declaração, está no seu banco de dados de usuários.
  • O endereço de e-mail na declaração corresponde a um usuário no seu banco de dados de usuários.

Se uma das condições for verdadeira, o usuário já se inscreveu. Nesse caso, retorne uma resposta como esta:

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

{
  "account_found":"true",
}

Se o ID da Conta do Google e o endereço de e-mail especificados na declaração não corresponderem a um usuário no seu banco de dados, o usuário ainda não se inscreveu. Nesse caso, o endpoint de troca de token precisa responder com um erro HTTP 404 que especifica "account_found": "false", como no exemplo a seguir:

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

{
  "account_found":"false",
}

Processar a vinculação automática (get intent)

Depois que o usuário autoriza o acesso ao perfil, o Google envia uma solicitação com uma declaração assinada da identidade do usuário. A declaração contém informações que incluem o ID, o nome e o endereço de e-mail da Conta do Google do usuário. O endpoint de troca de token configurado para seu projeto processa essa solicitação.

Se a Conta do Google correspondente já estiver presente no sistema de autenticação, o endpoint de troca de token retornará um token para o usuário. Se a Conta do Google não corresponder a um usuário existente, o endpoint de troca de token retornará um erro linking_error e um login_hint opcional.

A solicitação tem o seguinte formato:

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

O endpoint de troca de token precisa processar os seguintes parâmetros:

Parâmetros de endpoint de token
intent Para essas solicitações, o valor desse parâmetro é get.
grant_type O tipo de token que está sendo trocado. Para essas solicitações, o valor deste parâmetro é urn:ietf:params:oauth:grant-type:jwt-bearer.
assertion Um Token da Web JSON (JWT) que fornece uma declaração assinada da identidade do usuário do Google. O JWT contém informações que incluem o ID, o nome e o endereço de e-mail da Conta do Google do usuário.
scope Opcional: todos os escopos que você configurou para solicitar ao Google.
client_id ID do cliente atribuído ao Google
client_secret A chave secreta do cliente que você atribuiu ao Google

Para responder às solicitações de intent get, seu endpoint de troca de token precisa executar as seguintes etapas:

  • Validar e decodificar a declaração JWT.
  • Verifique se a Conta do Google já está presente no sistema de autenticação.
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.

Verificar se a Conta do Google já está presente no sistema de autenticação

Verifique se uma destas condições é verdadeira:

  • O ID da Conta do Google, encontrado no campo sub da declaração, está no seu banco de dados de usuários.
  • O endereço de e-mail na declaração corresponde a um usuário no seu banco de dados de usuários.

Se uma conta for encontrada para o usuário, emita um token de acesso e retorne os valores em um objeto JSON no corpo da resposta HTTPS, como no exemplo a seguir:

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

  "refresh_token": "REFRESH_TOKEN",

  "expires_in": SECONDS_TO_EXPIRATION
}

Em alguns casos, a vinculação da conta com base no token de ID pode falhar para o usuário. Se isso for feito por qualquer motivo, o endpoint de troca de token precisará responder com um erro HTTP 401 que especifique error=linking_error, como mostrado no exemplo a seguir:

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

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

Quando o Google recebe uma resposta de erro 401 com linking_error, ele envia o usuário para o endpoint de autorização com login_hint como um parâmetro. O usuário conclui a vinculação da conta usando o fluxo de vinculação OAuth no navegador.

Processar a criação de contas pelo Login do Google (criar intent)

Quando um usuário precisa criar uma conta no serviço, o Google faz uma solicitação ao endpoint de troca de token que especifica intent=create.

A solicitação tem o seguinte formato:

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

O endpoint de troca de tokens precisa processar os seguintes parâmetros:

Parâmetros de endpoint de token
intent Para essas solicitações, o valor desse parâmetro é create.
grant_type O tipo de token que está sendo trocado. Para essas solicitações, o valor deste parâmetro é urn:ietf:params:oauth:grant-type:jwt-bearer.
assertion Um Token da Web JSON (JWT) que fornece uma declaração assinada da identidade do usuário do Google. O JWT contém informações que incluem o ID, o nome e o endereço de e-mail da Conta do Google do usuário.
client_id ID do cliente atribuído ao Google
client_secret A chave secreta do cliente que você atribuiu ao Google

O JWT no parâmetro assertion contém o ID, o nome e o endereço de e-mail da Conta do Google do usuário, que podem ser usados para criar uma nova conta no serviço.

Para responder às solicitações de intent create, seu endpoint de troca de token precisa executar as seguintes etapas:

  • Validar e decodificar a declaração JWT.
  • Valide as informações do usuário e crie uma nova conta.
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.

Validar as informações do usuário e criar uma nova conta

Verifique se uma destas condições é verdadeira:

  • O ID da Conta do Google, encontrado no campo sub da declaração, está no seu banco de dados de usuários.
  • O endereço de e-mail na declaração corresponde a um usuário no seu banco de dados de usuários.

Se uma das condições for verdadeira, solicite que o usuário vincule a conta existente à Conta do Google. Para fazer isso, responda à solicitação com um erro HTTP 401 que especifique error=linking_error e forneça o endereço de e-mail do usuário como login_hint. Veja a seguir um exemplo de resposta:

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

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

Quando o Google recebe uma resposta de erro 401 com linking_error, ele envia o usuário para o endpoint de autorização com login_hint como um parâmetro. O usuário conclui a vinculação da conta usando o fluxo de vinculação OAuth no navegador.

Se nenhuma das condições for verdadeira, crie uma nova conta de usuário com as informações fornecidas no JWT. As novas contas normalmente não têm uma senha definida. É recomendável adicionar o Login do Google a outras plataformas para permitir que os usuários façam login com o Google nas plataformas do seu aplicativo. Outra opção é enviar por e-mail ao usuário um link que inicie o fluxo de recuperação de senha para permitir que ele defina uma senha para fazer login em outras plataformas.

Quando a criação estiver concluída, emita um token de acesso e de atualização e retorne os valores em um objeto JSON no corpo da resposta HTTPS, como no exemplo a seguir:

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

  "refresh_token": "REFRESH_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

您可以通过使用验证实现的OAuth 2.0游乐场工具。

在工具中,执行以下步骤:

  1. 单击配置打开的OAuth 2.0配置窗口。
  2. OAuth流场中,选择客户端
  3. OAuth端点字段中,选择自定义
  4. 在相应字段中指定您的 OAuth 2.0 端点和您分配给 Google 的客户端 ID。
  5. 步骤1部分,不要选择任何谷歌范围。相反,将此字段留空或键入对您的服务器有效的范围(如果不使用 OAuth 范围,则输入任意字符串)。当您完成后,单击授权的API。
  6. 步骤2步骤3段,完成OAuth 2.0流程和验证每个步骤按预期工作。

您可以通过验证您的实现谷歌帐户链接演示工具。

在工具中,执行以下步骤:

  1. 点击登录在与谷歌按钮。
  2. 选择您要关联的帐户。
  3. 输入服务标识。
  4. (可选)输入您将请求访问的一个或多个范围。
  5. 单击开始演示
  6. 出现提示时,确认您可以同意并拒绝链接请求。
  7. 确认您被重定向到您的平台。