Autenticar com um servidor de back-end

Se você usa o Login do Google com um app ou site que se comunica com um servidor de back-end, talvez seja necessário identificar o usuário conectado no servidor. Para fazer isso com segurança, depois que um usuário fizer login, envie o token do ID do usuário para o servidor usando HTTPS. Em seguida, no servidor, verifique a integridade do token de ID e use as informações do usuário contidas nele para estabelecer uma sessão ou criar uma nova conta.

Enviar o token do ID para seu servidor

Depois que um usuário fizer login, consiga o token de ID dele:

function onSignIn(googleUser) {
  var id_token = googleUser.getAuthResponse().id_token;
  ...
}

Em seguida, envie o token de ID para o seu servidor com uma solicitação HTTPS POST:

var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://yourbackend.example.com/tokensignin');
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onload = function() {
  console.log('Signed in as: ' + xhr.responseText);
};
xhr.send('idtoken=' + id_token);

Verificar a integridade do token de ID

Depois de receber o token de ID por HTTPS POST, verifique a integridade do token.

如需验证令牌是否有效,请确保: 满足条件:

  • ID 令牌已由 Google 正确签名。使用 Google 的公钥 (适用于 JWKPEM 格式) 以验证令牌的签名。这些密钥会定期轮替:检查 响应中的 Cache-Control 标头来确定何时 您应该再次检索它们。
  • ID 令牌中 aud 的值等于您应用的某个 客户端 ID必须进行此检查,以防止向恶意 应用用于访问应用的后端服务器上的同一用户的相关数据。
  • ID 令牌中 iss 的值等于 accounts.google.comhttps://accounts.google.com
  • ID 令牌的过期时间 (exp) 未过。
  • 如果您需要验证 ID 令牌是否代表 Google Workspace 或 Cloud 组织账号时,您可以查看 hd 声明,该声明表示托管的 用户的网域。将资源访问权限限制为只有 特定网域。缺少此声明即表示相应账号不属于 Google 托管的域名。

您可以使用 emailemail_verifiedhd 字段来确定 Google 负责托管电子邮件地址,并对其具有权威性。如果 Google 拥有权威性, 该用户就是所知的合法账号所有者,您可以跳过密码或其他输入框 验证方法。

Google 具有权威性的情形:

  • email 的后缀为 @gmail.com,这是一个 Gmail 账号。
  • email_verified 为 true 且 hd 已设置,这是 G Suite 账号。

用户无需使用 Gmail 或 G Suite 即可注册 Google 账号。时间 email 不包含 @gmail.com 后缀且 hd 不存在,Google 未 建议使用权威凭据和密码或其他验证方法进行验证 用户。email_verified 可能为 true,因为 Google 最初验证了 创建 Google 账号后,该用户会拥有第三方的所有权, 后,电子邮件账号可能已更改。

我们强烈建议不要自行编写代码来执行这些验证步骤, 建议您使用适用于您平台的 Google API 客户端库, JWT 库。对于开发和调试,您可以调用我们的 tokeninfo 验证端点。

Usar uma biblioteca de cliente das APIs do Google

Usar uma das bibliotecas de cliente das APIs do Google (por exemplo, Java, Node.js, PHP, Python) é a maneira recomendada de validar os tokens de ID do Google em um ambiente de produção.

Java

Para validar um token de ID em Java, use o objeto GoogleIdTokenVerifier. Exemplo:

import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;

...

GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory)
    // Specify the CLIENT_ID of the app that accesses the backend:
    .setAudience(Collections.singletonList(CLIENT_ID))
    // Or, if multiple clients access the backend:
    //.setAudience(Arrays.asList(CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3))
    .build();

// (Receive idTokenString by HTTPS POST)

GoogleIdToken idToken = verifier.verify(idTokenString);
if (idToken != null) {
  Payload payload = idToken.getPayload();

  // Print user identifier
  String userId = payload.getSubject();
  System.out.println("User ID: " + userId);

  // Get profile information from payload
  String email = payload.getEmail();
  boolean emailVerified = Boolean.valueOf(payload.getEmailVerified());
  String name = (String) payload.get("name");
  String pictureUrl = (String) payload.get("picture");
  String locale = (String) payload.get("locale");
  String familyName = (String) payload.get("family_name");
  String givenName = (String) payload.get("given_name");

  // Use or store profile information
  // ...

} else {
  System.out.println("Invalid ID token.");
}

O método GoogleIdTokenVerifier.verify() verifica a assinatura JWT, as declarações aud, iss e exp.

Se você precisar validar que o token de ID representa uma conta de organização do Google Workspace ou do Cloud, verifique a declaração hd conferindo o nome de domínio retornado pelo método Payload.getHostedDomain(). O domínio da declaração email não é suficiente para garantir que a conta seja gerenciada por um domínio ou organização.

Node.js

Para validar um token de ID no Node.js, use a Biblioteca Google Auth para Node.js. Instale a biblioteca:

npm install google-auth-library --save
. Em seguida, chame a função verifyIdToken(). Exemplo:

const {OAuth2Client} = require('google-auth-library');
const client = new OAuth2Client();
async function verify() {
  const ticket = await client.verifyIdToken({
      idToken: token,
      audience: CLIENT_ID,  // Specify the CLIENT_ID of the app that accesses the backend
      // Or, if multiple clients access the backend:
      //[CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3]
  });
  const payload = ticket.getPayload();
  const userid = payload['sub'];
  // If the request specified a Google Workspace domain:
  // const domain = payload['hd'];
}
verify().catch(console.error);

A função verifyIdToken verifica a assinatura JWT, a declaração aud, a declaração exp e a declaração iss.

Se você precisar validar se o token de ID representa uma conta de organização do Google Workspace ou do Cloud, verifique a declaração hd, que indica o domínio hospedado do usuário. Precisa ser usado para restringir o acesso a um recurso apenas a membros de determinados domínios. A ausência dessa declaração indica que a conta não pertence a um domínio hospedado pelo Google.

PHP

Para validar um token de ID em PHP, use a biblioteca de cliente de APIs do Google para PHP. Instale a biblioteca (por exemplo, usando o Composer):

composer require google/apiclient
. Em seguida, chame a função verifyIdToken(). Exemplo:

require_once 'vendor/autoload.php';

// Get $id_token via HTTPS POST.

$client = new Google_Client(['client_id' => $CLIENT_ID]);  // Specify the CLIENT_ID of the app that accesses the backend
$payload = $client->verifyIdToken($id_token);
if ($payload) {
  $userid = $payload['sub'];
  // If the request specified a Google Workspace domain
  //$domain = $payload['hd'];
} else {
  // Invalid ID token
}

A função verifyIdToken verifica a assinatura JWT, a declaração aud, a declaração exp e a declaração iss.

Se você precisar validar se o token de ID representa uma conta de organização do Google Workspace ou do Cloud, verifique a declaração hd, que indica o domínio hospedado do usuário. Precisa ser usado para restringir o acesso a um recurso apenas a membros de determinados domínios. A ausência dessa declaração indica que a conta não pertence a um domínio hospedado pelo Google.

Python

Para validar um token de ID em Python, use a função verify_oauth2_token. Exemplo:

from google.oauth2 import id_token
from google.auth.transport import requests

# (Receive token by HTTPS POST)
# ...

try:
    # Specify the CLIENT_ID of the app that accesses the backend:
    idinfo = id_token.verify_oauth2_token(token, requests.Request(), CLIENT_ID)

    # Or, if multiple clients access the backend server:
    # idinfo = id_token.verify_oauth2_token(token, requests.Request())
    # if idinfo['aud'] not in [CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3]:
    #     raise ValueError('Could not verify audience.')

    # If the request specified a Google Workspace domain
    # if idinfo['hd'] != DOMAIN_NAME:
    #     raise ValueError('Wrong domain name.')

    # ID token is valid. Get the user's Google Account ID from the decoded token.
    userid = idinfo['sub']
except ValueError:
    # Invalid token
    pass

A função verify_oauth2_token verifica a assinatura JWT, a declaração aud e a declaração exp. Também é preciso verificar a declaração hd (se aplicável) examinando o objeto retornado por verify_oauth2_token. Se vários clientes acessarem o servidor de back-end, verifique também a declaração aud manualmente.

Como chamar o endpoint tokeninfo

Uma maneira fácil de validar uma assinatura de token de ID para depuração é usar o endpoint tokeninfo. Chamar esse endpoint envolve uma outra solicitação de rede que faz a maior parte da validação enquanto você testa a validação adequada e a extração de payload no seu próprio código. Ele não é adequado para uso em código de produção, porque as solicitações podem ser limitadas ou sujeitas a erros intermitentes.

Para validar um token de ID usando o endpoint tokeninfo, faça uma solicitação HTTPS POST ou GET para o endpoint e transmita seu token de ID no parâmetro id_token. Por exemplo, para validar o token "XYZ123", faça a seguinte solicitação GET:

https://oauth2.googleapis.com/tokeninfo?id_token=XYZ123

Se o token estiver assinado corretamente e as declarações iss e exp tiverem os valores esperados, você receberá uma resposta HTTP 200, em que o corpo contém as declarações de token de ID formatado em JSON. Veja um exemplo de resposta:

{
 // These six fields are included in all Google ID Tokens.
 "iss": "https://accounts.google.com",
 "sub": "110169484474386276334",
 "azp": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
 "aud": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
 "iat": "1433978353",
 "exp": "1433981953",

 // These seven fields are only included when the user has granted the "profile" and
 // "email" OAuth scopes to the application.
 "email": "testuser@gmail.com",
 "email_verified": "true",
 "name" : "Test User",
 "picture": "https://lh4.googleusercontent.com/-kYgzyAWpZzJ/ABCDEFGHI/AAAJKLMNOP/tIXL9Ir44LE/s99-c/photo.jpg",
 "given_name": "Test",
 "family_name": "User",
 "locale": "en"
}

Se você precisar confirmar que o token de ID representa uma conta do Google Workspace, verifique a declaração hd, que indica o domínio hospedado do usuário. Precisa ser usado para restringir o acesso a um recurso apenas a membros de determinados domínios. A ausência dessa declaração indica que a conta não pertence a um domínio hospedado do Google Workspace.

Criar uma conta ou sessão

Depois de verificar o token, verifique se o usuário já está no banco de dados de usuários. Se for o caso, estabeleça uma sessão autenticada para o usuário. Se o usuário ainda não estiver no banco de dados, crie um novo registro usando as informações no payload do token de ID e estabeleça uma sessão para o usuário. Você pode solicitar outras informações de perfil necessárias ao detectar um usuário recém-criado no app.

Como proteger as contas dos usuários com a Proteção entre contas

Ao confiar no Google para fazer o login de um usuário, você aproveita automaticamente todos os recursos de segurança e a infraestrutura que o Google criou para proteger os dados do usuário. No entanto, no caso improvável de a Conta do Google do usuário ser comprometida ou de alguma outra ocorrência de segurança significativa, seu app também poderá ficar vulnerável a ataques. Para proteger melhor suas contas contra grandes ocorrências de segurança, use a Proteção entre contas para receber alertas de segurança do Google. Ao receber esses eventos, você confere mudanças importantes na segurança da Conta do Google do usuário e pode tomar medidas no seu serviço para proteger suas contas.