Si usas el Acceso con Google en una app o sitio que se comunica con un servidor de backend, es posible que debas identificar al usuario con una sesión activa en el servidor. Para hacerlo de manera segura, después de que un usuario acceda correctamente, envía el token de ID del usuario a tu servidor mediante HTTPS. Luego, en el servidor, verifica la integridad del token de ID y usa la información del usuario que este contiene para establecer una sesión o crear una cuenta nueva.
Envía el token de ID a tu servidor
Una vez que un usuario acceda correctamente, obtén su token de ID:
function onSignIn(googleUser) { var id_token = googleUser.getAuthResponse().id_token; ... }
Luego, envía el token de ID a tu servidor con una solicitud 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);
Verifica la integridad del token de ID
Después de recibir el token de ID mediante HTTPS POST, debes verificar su integridad.
To verify that the token is valid, ensure that the following criteria are satisfied:
- The ID token is properly signed by Google. Use Google's public keys
(available in
JWK or
PEM format)
to verify the token's signature. These keys are regularly rotated; examine
the
Cache-Control
header in the response to determine when you should retrieve them again. - The value of
aud
in the ID token is equal to one of your app's client IDs. This check is necessary to prevent ID tokens issued to a malicious app being used to access data about the same user on your app's backend server. - The value of
iss
in the ID token is equal toaccounts.google.com
orhttps://accounts.google.com
. - The expiry time (
exp
) of the ID token has not passed. - If you want to restrict access to only members of your G Suite domain,
verify that the ID token has an
hd
claim that matches your G Suite domain name.
Rather than writing your own code to perform these verification steps, we strongly
recommend using a Google API client library for your platform, or a general-purpose
JWT library. For development and debugging, you can call our tokeninfo
validation endpoint.
Usa una biblioteca cliente de la API de Google
El uso de una de las bibliotecas cliente de la API de Google (p.ej., Java, Node.js, PHP o Python) es la forma recomendada de validar tokens de ID de Google en un entorno de producción.
Para validar un token de ID en Java, utiliza el objeto GoogleIdTokenVerifier. Por ejemplo:
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."); }
El método GoogleIdTokenVerifier.verify()
verifica la firma de JWT, la reclamación aud
, la reclamación iss
y exp
.
Si deseas restringir el acceso solo a los miembros de tu dominio de G Suite, verifica también la reclamación hd
en el nombre de dominio que muestra el método Payload.getHostedDomain()
.
Para validar un token de ID en Node.js, usa la biblioteca de Google Auth para Node.js. Instala la biblioteca:
npm install google-auth-library --saveLuego, llama a la función
verifyIdToken()
. Por ejemplo:
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 request specified a G Suite domain: // const domain = payload['hd']; } verify().catch(console.error);
La función verifyIdToken
verifica la firma de JWT, la reclamación aud
, la reclamación exp
y iss
.
Si deseas restringir el acceso solo a los miembros de tu dominio de G Suite, verifica también que la reclamación hd
coincida con el nombre de tu dominio de G Suite.
Para validar un token de ID en PHP, usa la biblioteca cliente de la API de Google para PHP. Instala la biblioteca (por ejemplo, con Composer):
composer require google/apiclientLuego, llama a la función
verifyIdToken()
. Por ejemplo:
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 request specified a G Suite domain: //$domain = $payload['hd']; } else { // Invalid ID token }
La función verifyIdToken
verifica la firma de JWT, la reclamación aud
, la reclamación exp
y iss
.
Si deseas restringir el acceso solo a los miembros de tu dominio de G Suite, verifica también que la reclamación hd
coincida con el nombre de tu dominio de G Suite.
Para validar un token de ID en Python, usa la función verify_oauth2_token. Por ejemplo:
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 auth request is from a G Suite domain: # if idinfo['hd'] != GSUITE_DOMAIN_NAME: # raise ValueError('Wrong hosted domain.') # ID token is valid. Get the user's Google Account ID from the decoded token. userid = idinfo['sub'] except ValueError: # Invalid token pass
La función verify_oauth2_token
verifica la firma de JWT y la reclamación aud
y exp
.
También debes verificar la reclamación hd
(si corresponde) examinando el objeto que muestra verify_oauth2_token
. Si varios clientes acceden al servidor de backend, también verifica de forma manual la reclamación aud
.
Llama al extremo tokeninfo
Una forma sencilla de validar una firma de token de ID para la depuración es usar el extremo tokeninfo
. Llamar a este extremo implica una solicitud de red adicional que realiza la mayor parte de la validación por ti mientras pruebas la validación y la extracción de carga útil adecuadas en tu propio código. No es adecuada para su uso en código de producción, ya que las solicitudes pueden limitarse o estar sujetas a errores intermitentes.
Para validar un token de ID con el extremo tokeninfo
, realiza una solicitud HTTPS POST o GET al extremo y pasa el token de ID en el parámetro id_token
.
Por ejemplo, para validar el token "XYZ123", realiza la siguiente solicitud GET:
https://oauth2.googleapis.com/tokeninfo?id_token=XYZ123
Si el token está firmado correctamente y las reclamaciones iss
y exp
tienen los valores esperados, obtendrás una respuesta HTTP 200, en la que el cuerpo contiene las reclamaciones de token de ID con formato JSON.
Esta es una respuesta de ejemplo:
{ // 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" }
Si eres cliente de G Suite, también puede interesarte la reclamación hd
, que indica el dominio alojado del usuario. Se puede usar para restringir el acceso
a un recurso solo a miembros de ciertos dominios. La ausencia de este reclamo indica que el usuario no pertenece a un dominio alojado en G Suite.
Crea una cuenta o sesión
Después de verificar el token, comprueba si el usuario ya se encuentra en tu base de datos de usuarios. De ser así, establece una sesión autenticada para el usuario. Si el usuario aún no se encuentra en tu base de datos, crea un registro de usuario nuevo a partir de la información de la carga útil del token de ID y establece una sesión para el usuario. Puedes solicitarle al usuario cualquier información de perfil adicional que necesites cuando detectas un usuario recién creado en tu app.
Cómo proteger las cuentas de tus usuarios con la Protección integral de la cuenta
Si dependes de Google para que un usuario acceda, te beneficiarás automáticamente de todas las funciones de seguridad y la infraestructura que Google creó para proteger los datos del usuario. Sin embargo, en el caso improbable de que la Cuenta de Google del usuario se vea comprometida o de que se produzca algún otro evento de seguridad importante, tu app también podría ser vulnerable a ataques. Para proteger mejor tus cuentas de cualquier evento de seguridad importante, usa la Protección integral de la cuenta para recibir alertas de seguridad de Google. Cuando recibes estos eventos, obtienes visibilidad de los cambios importantes en la seguridad de la Cuenta de Google del usuario y puedes tomar medidas en el servicio para proteger tus cuentas.