Si vous utilisez Google Sign-In avec une application ou un site qui communique avec un serveur backend, vous devrez peut-être identifier l'utilisateur actuellement connecté sur le serveur. Pour ce faire de manière sécurisée, une fois qu'un utilisateur s'est connecté, envoyez le jeton d'ID de l'utilisateur à votre serveur via HTTPS. Ensuite, sur le serveur, vérifiez l'intégrité du jeton d'ID et utilisez les informations utilisateur contenues dans le jeton pour établir une session ou créer un compte.
Envoyer le jeton d'ID à votre serveur
Une fois qu'un utilisateur s'est connecté, récupérez son jeton d'ID:
Swift
GIDSignIn.sharedInstance.signIn(withPresenting: self) { signInResult, error in guard error == nil else { return } guard let signInResult = signInResult else { return } signInResult.user.refreshTokensIfNeeded { user, error in guard error == nil else { return } guard let user = user else { return } let idToken = user.idToken // Send ID token to backend (example below). } }
Objective-C
[GIDSignIn.sharedInstance signInWithPresentingViewController:self completion:^(GIDSignInResult * _Nullable signInResult, NSError * _Nullable error) { if (error) { return; } if (signInResult == nil) { return; } [signInResult.user refreshTokensIfNeededWithCompletion:^(GIDGoogleUser * _Nullable user, NSError * _Nullable error) { if (error) { return; } if (user == nil) { return; } NSString *idToken = user.idToken; // Send ID token to backend (example below). }]; }];
Envoyez ensuite le jeton d'ID à votre serveur avec une requête HTTPS POST:
Swift
func tokenSignInExample(idToken: String) { guard let authData = try? JSONEncoder().encode(["idToken": idToken]) else { return } let url = URL(string: "https://yourbackend.example.com/tokensignin")! var request = URLRequest(url: url) request.httpMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Content-Type") let task = URLSession.shared.uploadTask(with: request, from: authData) { data, response, error in // Handle response from your backend. } task.resume() }
Objective-C
NSString *signinEndpoint = @"https://yourbackend.example.com/tokensignin"; NSDictionary *params = @{@"idtoken": idToken}; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:signinEndpoint]; [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; [request setHTTPMethod:@"POST"]; [request setHTTPBody:[self httpBodyForParamsDictionary:params]]; NSOperationQueue *queue = [[NSOperationQueue alloc] init]; [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { if (error) { NSLog(@"Error: %@", error.localizedDescription); } else { NSLog(@"Signed in as %@", data.bytes); } }];
Vérifier l'intégrité du jeton d'ID
Après avoir reçu le jeton d'ID via HTTPS POST, vous devez vérifier son intégrité.
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.
Utiliser une bibliothèque cliente des API Google
Il est recommandé d'utiliser l'une des bibliothèques clientes des API Google (par exemple, Java, Node.js, PHP, Python) pour valider les jetons d'ID Google dans un environnement de production.
Pour valider un jeton d'ID en Java, utilisez l'objet GoogleIdTokenVerifier. Exemple :
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."); }
La méthode GoogleIdTokenVerifier.verify()
vérifie la signature JWT, la revendication aud
, la revendication iss
et la revendication exp
.
Si vous souhaitez limiter l'accès aux membres de votre domaine G Suite, validez également la revendication hd
en vérifiant le nom de domaine renvoyé par la méthode Payload.getHostedDomain()
.
Pour valider un jeton d'ID en Node.js, utilisez la bibliothèque Google Auth pour Node.js. Installez la bibliothèque :
npm install google-auth-library --save. Appelez ensuite la fonction
verifyIdToken()
. Exemple :
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 fonction verifyIdToken
vérifie la signature JWT, la revendication aud
, la revendication exp
et la revendication iss
.
Si vous souhaitez limiter l'accès aux membres de votre domaine G Suite, vérifiez également que la revendication hd
correspond au nom de votre domaine G Suite.
Pour valider un jeton d'ID en PHP, utilisez la bibliothèque cliente des API Google pour PHP. Installez la bibliothèque (par exemple, à l'aide de Composer) :
composer require google/apiclient, appelez ensuite la fonction
verifyIdToken()
. Exemple :
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 fonction verifyIdToken
vérifie la signature JWT, la revendication aud
, la revendication exp
et la revendication iss
.
Si vous souhaitez limiter l'accès aux membres de votre domaine G Suite, vérifiez également que la revendication hd
correspond au nom de votre domaine G Suite.
Pour valider un jeton d'ID en Python, utilisez la fonction verify_oauth2_token. Exemple :
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 fonction verify_oauth2_token
vérifie la signature JWT, la revendication aud
et la revendication exp
.
Vous devez également vérifier la revendication hd
(le cas échéant) en examinant l'objet renvoyé par verify_oauth2_token
. Si plusieurs clients accèdent au serveur backend, validez également manuellement la revendication aud
.
Appeler le point de terminaison tokeninfo
Un moyen simple de valider une signature de jeton d'ID pour le débogage consiste à utiliser le point de terminaison tokeninfo
. L'appel de ce point de terminaison implique une requête réseau supplémentaire qui effectue la majeure partie de la validation pendant que vous testez la validation et l'extraction de la charge utile appropriées dans votre propre code. Il n'est pas adapté à l'utilisation dans le code de production, car les requêtes peuvent être limitées ou soumises à des erreurs intermittentes.
Pour valider un jeton d'ID à l'aide du point de terminaison tokeninfo
, envoyez une requête HTTPS POST ou GET au point de terminaison, puis transmettez votre jeton d'ID dans le paramètre id_token
.
Par exemple, pour valider le jeton "XYZ123", envoyez la requête GET suivante:
https://oauth2.googleapis.com/tokeninfo?id_token=XYZ123
Si le jeton est correctement signé et que les revendications iss
et exp
ont les valeurs attendues, vous obtiendrez une réponse HTTP 200, dont le corps contient les revendications de jeton d'ID au format JSON.
Voici un exemple de réponse :
{ // 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 vous êtes un client G Suite, la revendication hd
, qui indique le domaine hébergé de l'utilisateur, peut également vous intéresser. Cela permet de limiter l'accès à une ressource aux seuls membres de certains domaines. L'absence de cette revendication indique que l'utilisateur n'appartient pas à un domaine hébergé par G Suite.
Créer un compte ou une session
Après avoir vérifié le jeton, vérifiez si l'utilisateur figure déjà dans votre base de données des utilisateurs. Le cas échéant, établissez une session authentifiée pour l'utilisateur. Si l'utilisateur ne figure pas encore dans votre base de données utilisateur, créez un enregistrement utilisateur à partir des informations contenues dans la charge utile du jeton d'ID, puis établissez une session pour l'utilisateur. Vous pouvez demander à l'utilisateur toute information de profil supplémentaire dont vous avez besoin lorsque vous détectez un nouvel utilisateur dans votre application.
Sécuriser les comptes de vos utilisateurs avec la protection multicompte
Lorsque vous utilisez Google pour connecter un utilisateur, vous bénéficiez automatiquement de toutes les fonctionnalités de sécurité et de l'infrastructure que Google a développées pour protéger les données de l'utilisateur. Toutefois, dans le cas peu probable où le compte Google de l'utilisateur serait compromis ou en cas d'autre événement de sécurité important, votre application pourrait être vulnérable aux attaques. Pour mieux protéger vos comptes contre les événements de sécurité majeurs, utilisez la protection multicompte afin de recevoir des alertes de sécurité de la part de Google. Lorsque vous recevez ces événements, vous gagnez en visibilité sur les modifications importantes apportées à la sécurité du compte Google de l'utilisateur. Vous pouvez ensuite prendre des mesures concernant votre service pour sécuriser vos comptes.