Vinculação simplificada com OAuth e login do Google

Visão geral

O link simplificado do Login do Google baseado em OAuth adiciona o Login do Google ao link do OAuth . Isso fornece uma experiência de vinculação perfeita para os usuários do Google e também permite a vinculação de contas para usuários que se registraram em seu serviço com uma identidade que não seja do Google.

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

  1. Primeiro, peça ao usuário consentimento para acessar seu perfil do Google.
  2. Use as informações em seu perfil para verificar se a conta de usuário existe.
  3. Para usuários existentes, vincule as contas.
  4. Se você não conseguir encontrar uma correspondência para o usuário do Google em seu sistema de autenticação, valide o token de ID recebido do Google. Você pode então criar um usuário com base nas informações de perfil contidas no token de ID.

Figura 3 . Vinculação de conta no telefone de um usuário com vinculação simplificada

As contas são vinculadas usando fluxos de código de autorização e implícito OAuth 2.0 padrão da indústria. Seu serviço deve oferecer suporte a autorização compatível com OAuth 2.0 e pontos de extremidade de troca de token . Além disso, seu ponto de extremidade de troca de token deve oferecer suporte a asserções JSON Web Token (JWT) e implementar as intenções de check , create e get .

Obtenha seu ID de cliente e segredo da API do Google

Você precisará obter seu ID de cliente e segredo da API usando o projeto criado ao concluir as etapas de vinculação OAuth . Para fazer isso, conclua as seguintes etapas:

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

    Se o seu projeto não tiver um ID de cliente para o tipo de aplicativo da Web, clique em Criar credenciais> ID de cliente OAuth para criar um. Certifique-se de incluir o domínio do seu site na caixa Origens de JavaScript autorizadas . Ao realizar testes ou desenvolvimento locais, você deve adicionar http://localhost e http://localhost:<port_number> ao campo Authorized JavaScript origins .

Implementar seu servidor OAuth

Verifique se há uma conta de usuário existente

Depois que o usuário dá consentimento para acessar seu perfil do Google, o Google envia uma solicitação que contém uma declaração assinada da identidade do usuário do Google. A declaração contém informações que incluem a ID, o nome e o endereço de e-mail da Conta do Google do usuário. O ponto de extremidade de troca de token configurado para seu projeto lida com essa solicitação.

Se a conta do Google correspondente já estiver presente em seu sistema de autenticação, seu ponto de extremidade de troca de token responde com account_found=true . Se a conta do Google não corresponder a um usuário existente, seu ponto de extremidade de troca de token retornará um erro HTTP 404 não encontrado 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

Seu ponto de extremidade de troca de token deve ser capaz de lidar com os seguintes parâmetros:

Parâmetros de terminal 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, esse parâmetro tem o valor urn:ietf:params:oauth:grant-type:jwt-bearer .
assertion Um JSON Web Token (JWT) que fornece uma declaração assinada da identidade do usuário do Google. O JWT contém informações que incluem a ID, o nome e o endereço de e-mail da Conta do Google do usuário.

Quando seu ponto de extremidade de troca de token recebe a solicitação de check , ele precisa validar e decodificar a asserção 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.

Verifique se a conta do Google já está presente em seu sistema de autenticação

Verifique se alguma das seguintes condições é verdadeira:

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

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

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

{
  "account_found":"true",
}

O Google então exibe uma caixa de diálogo de consentimento de vinculação para o usuário e solicita consentimento para os escopos desejados a fim de continuar com a vinculação. Depois que o Google obtém o consentimento do usuário, ele envia uma solicitação get ao endpoint do token para continuar a vinculação.

Se nem o ID da conta do Google nem o endereço de e-mail especificado na declaração corresponder a um usuário em seu banco de dados, o usuário ainda não se inscreveu. Nesse caso, seu ponto de extremidade 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",
}
Quando o Google recebe a resposta de erro 404 com um erro "account_found": "false" , o Google exibe uma caixa de diálogo para o usuário solicitar consentimento para criar uma nova conta e acesso aos escopos desejados. Depois que o Google obtém o consentimento do usuário, ele chama seu ponto de extremidade de troca de tokens com o valor do parâmetro intent definido para create e inclui um token de ID que contém as informações de perfil do usuário com a solicitação.

Lidar com vinculação automática

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

Se a conta do Google correspondente já estiver presente em seu sistema de autenticação, seu ponto de extremidade de troca de token retorna um token para o usuário. Se a conta do Google não corresponder a um usuário existente, seu ponto de extremidade de troca de token retornará um erro linking_error e login_hint opcional.

O pedido 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

Seu ponto de extremidade de troca de token deve ser capaz de lidar com os seguintes parâmetros:

Parâmetros de terminal 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, esse parâmetro tem o valor urn:ietf:params:oauth:grant-type:jwt-bearer .
assertion Um JSON Web Token (JWT) que fornece uma declaração assinada da identidade do usuário do Google. O JWT contém informações que incluem a 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 o Google para solicitar dos usuários.

Quando seu ponto de extremidade de troca de token recebe a solicitação de vinculação, ele precisa validar e decodificar a declaração 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.

Verifique se a conta do Google já está presente em seu sistema de autenticação

Verifique se alguma das seguintes condições é verdadeira:

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

Em alguns casos, a vinculação de contas com base no token de ID pode falhar para o usuário. Se isso acontecer por qualquer motivo, seu ponto de extremidade de troca de token precisa responder com um erro HTTP 401 que especifica error=linking_error , como mostra o 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 , o Google chama seu endpoint de troca de token com o seguinte na solicitação:

  • O parâmetro de intent definido para create
  • Um JWT com o token de ID e informações de perfil do usuário

Lidar com a criação de contas por meio do Login do Google

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

O pedido 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[&NEW_ACCOUNT_INFO]

Seu ponto de extremidade de troca de token deve ser capaz de lidar com os seguintes parâmetros:

Parâmetros de terminal 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, esse parâmetro tem o valor urn:ietf:params:oauth:grant-type:jwt-bearer .
assertion Um JSON Web Token (JWT) que fornece uma declaração assinada da identidade do usuário do Google. O JWT contém informações que incluem a ID, o nome e o endereço de e-mail da Conta do Google do usuário.

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 você pode usar para criar uma nova conta em seu serviço.

Para responder às solicitações de criação de conta, seu ponto de extremidade de troca de token deve executar as etapas nas duas seções a seguir.

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.

Valide as informações do usuário e crie uma nova conta

Verifique se alguma das seguintes condições é verdadeira:

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

Se alguma das condições for verdadeira, solicite ao usuário que vincule sua conta existente à Conta do Google. Para fazer isso, responda à solicitação com um erro HTTP 401 que especifica error=linking_error e fornece o endereço de e-mail do usuário como login_hint . A seguir está 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 , o Google envia o usuário ao seu endpoint de autorização com login_hint como parâmetro. O usuário conclui a vinculação da conta usando o fluxo de vinculação OAuth em seu navegador.

Se nenhuma das condições for verdadeira, crie uma nova conta de usuário com as informações fornecidas no JWT. Normalmente, as novas contas 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 superfícies de seu aplicativo. Como alternativa, você pode enviar um e-mail ao usuário com um link que inicia seu fluxo de recuperação de senha para permitir que o usuário defina uma senha para fazer login em outras plataformas.

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

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

  "expires_in": SECONDS_TO_EXPIRATION
}

Validando sua implementação

Você pode validar sua implementação usando a ferramenta OAuth 2.0 Playground .

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 Lado do cliente .
  3. No campo Pontos de extremidade OAuth , 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 seção Etapa 1 , não selecione nenhum escopo do Google. Em vez disso, deixe este campo em branco ou digite um escopo válido para seu servidor (ou uma string arbitrária se você não usar escopos OAuth). Quando terminar, clique em Autorizar APIs .
  6. Nas seções Etapa 2 e Etapa 3 , passe pelo fluxo do OAuth 2.0 e verifique se cada etapa funciona conforme o esperado.

Você pode validar sua implementação usando a ferramenta de demonstração de vinculação de contas do Google .

Na ferramenta, execute as seguintes etapas:

  1. Clique no botão Sign-in with 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.