OAuth 2.0 pour les applications Web côté client

Ce document explique comment implémenter l'autorisation OAuth 2.0 pour accéder aux API Google à partir d'une application Web JavaScript. OAuth 2.0 permet aux utilisateurs de partager des données spécifiques avec une application tout en préservant la confidentialité de leurs noms d'utilisateur, mots de passe et autres informations. Par exemple, une application peut utiliser OAuth 2.0 pour obtenir l'autorisation des utilisateurs de stocker des fichiers dans leur Google Drive.

Ce flux OAuth 2.0 est appelé flux d'autorisation implicite. Il est conçu pour les applications qui n'accèdent aux API que lorsque l'utilisateur est présent dans l'application. Ces applications ne peuvent pas stocker d'informations confidentielles.

Dans ce flux, votre application ouvre une URL Google qui utilise des paramètres de requête pour identifier votre application et le type d'accès à l'API dont elle a besoin. Vous pouvez ouvrir l'URL dans la fenêtre du navigateur actuelle ou dans un pop-up. L'utilisateur peut s'authentifier avec Google et accorder les autorisations demandées. Google redirige ensuite l'utilisateur vers votre application. La redirection inclut un jeton d'accès, que votre application vérifie, puis utilise pour effectuer des requêtes API.

Bibliothèque cliente des API Google et services d'identité Google

Si vous utilisez la bibliothèque cliente des API Google pour JavaScript pour effectuer des appels autorisés à Google, vous devez utiliser la bibliothèque JavaScript Google Identity Services pour gérer le flux OAuth 2.0. Veuillez consulter le modèle de jeton de Google Identity Services, qui est basé sur le flux autorisation implicite OAuth 2.0.

Prérequis

Activer les API pour votre projet.

Toute application qui appelle des API Google doit les activer dans API Console.

Pour activer une API pour votre projet:

  1. Open the API Library dans le Google API Console.
  2. If prompted, select a project, or create a new one.
  3. API Library répertorie toutes les API disponibles, regroupées par famille de produits et par popularité. Si l'API que vous souhaitez activer n'apparaît pas dans la liste, utilisez la fonctionnalité de recherche pour la trouver ou cliquez sur Tout afficher dans la famille de produits à laquelle elle appartient.
  4. Sélectionnez l'API que vous souhaitez activer, puis cliquez sur le bouton Activer.
  5. If prompted, enable billing.
  6. If prompted, read and accept the API's Terms of Service.

Créer des identifiants d'autorisation

Toute application qui utilise OAuth 2.0 pour accéder aux API Google doit disposer d'identifiants d'autorisation qui identifient l'application auprès du serveur OAuth 2.0 de Google. Les étapes suivantes expliquent comment créer des identifiants pour votre projet. Vos applications peuvent ensuite utiliser les identifiants pour accéder aux API que vous avez activées pour ce projet.

  1. Go to the Credentials page.
  2. Cliquez sur Créer des identifiants > ID client OAuth.
  3. Sélectionnez le type d'application Application Web.
  4. Remplissez le formulaire. Les applications qui utilisent JavaScript pour envoyer des requêtes d'API Google autorisées doivent spécifier des origines JavaScript autorisées. Les origines identifient les domaines à partir desquels votre application peut envoyer des requêtes au serveur OAuth 2.0. Ces origines doivent respecter les Règles de validation de Google.

Identifier les niveaux d'accès

Les champs d'application permettent à votre application de demander uniquement l'accès aux ressources dont elle a besoin, tout en permettant aux utilisateurs de contrôler le nombre d'accès qu'ils accordent à votre application. Par conséquent, il peut exister une relation inverse entre le nombre de champs d'application demandés et la probabilité d'obtenir le consentement de l'utilisateur.

Avant de commencer à implémenter l'autorisation OAuth 2.0, nous vous recommandons d'identifier les champs d'application pour lesquels votre application aura besoin d'une autorisation d'accès.

Le document Champs d'application des API OAuth 2.0 contient la liste complète des champs d'application que vous pouvez utiliser pour accéder aux API Google.

Obtenir des jetons d'accès OAuth 2.0

Les étapes suivantes montrent comment votre application interagit avec le serveur OAuth 2.0 de Google pour obtenir le consentement d'un utilisateur afin d'effectuer une requête API en son nom. Votre application doit disposer de ce consentement avant de pouvoir exécuter une requête d'API Google nécessitant l'autorisation de l'utilisateur.

Étape 1: Rediriger vers le serveur OAuth 2.0 de Google

Pour demander l'autorisation d'accéder aux données d'un utilisateur, redirigez-le vers le serveur OAuth 2.0 de Google.

Points de terminaison OAuth 2.0

Générez une URL pour demander l'accès au point de terminaison OAuth 2.0 de Google sur https://accounts.google.com/o/oauth2/v2/auth. Ce point de terminaison est accessible via HTTPS. Les connexions HTTP simples sont refusées.

Le serveur d'autorisation Google est compatible avec les paramètres de chaîne de requête suivants pour les applications de serveur Web:

Paramètres
client_id Obligatoire

ID client de votre application. Vous pouvez trouver cette valeur dans le API Console Credentials page.

redirect_uri Obligatoire

Détermine vers quelle page le serveur d'API redirige l'utilisateur une fois qu'il a terminé le flux d'autorisation. La valeur doit correspondre exactement à l'un des URI de redirection autorisés pour le client OAuth 2.0, que vous avez configuré dans le API Console Credentials pagede votre client. Si cette valeur ne correspond pas à un URI de redirection autorisé pour le client_id fourni, une erreur redirect_uri_mismatch s'affiche.

Notez que le schéma http ou https, la casse et la barre oblique finale ("/") doivent tous correspondre.

response_type Obligatoire

Les applications JavaScript doivent définir la valeur du paramètre sur token. Cette valeur indique au serveur d'autorisation Google de renvoyer le jeton d'accès sous la forme d'une paire name=value dans l'identifiant de fragment de l'URI (#) vers lequel l'utilisateur est redirigé une fois le processus d'autorisation terminé.

scope Obligatoire

Liste des champs d'application séparés par des espaces qui identifient les ressources auxquelles votre application peut accéder pour le compte de l'utilisateur. Ces valeurs renseignent l'écran de consentement que Google affiche à l'utilisateur.

Les champs d'application permettent à votre application de demander uniquement l'accès aux ressources dont elle a besoin, tout en permettant aux utilisateurs de contrôler le nombre d'accès qu'ils accordent à votre application. Par conséquent, il existe une relation inverse entre le nombre de champs d'application demandés et la probabilité d'obtenir le consentement de l'utilisateur.

Nous vous recommandons de demander à votre application d'accéder aux portées d'autorisation dans le contexte chaque fois que cela est possible. En demandant l'accès aux données utilisateur en contexte, via une autorisation incrémentielle, vous aidez les utilisateurs à comprendre plus facilement pourquoi votre application a besoin de l'accès qu'elle demande.

state Recommandé

Spécifie toute valeur de chaîne que votre application utilise pour maintenir l'état entre votre demande d'autorisation et la réponse du serveur d'autorisation. Le serveur renvoie la valeur exacte que vous envoyez en tant que paire name=value dans l'identifiant de fragment d'URL (#) de l'redirect_uri une fois que l'utilisateur a accepté ou refusé la requête d'accès de votre application.

Vous pouvez utiliser ce paramètre à plusieurs fins, par exemple pour rediriger l'utilisateur vers la ressource appropriée dans votre application, envoyer des nonces et atténuer la falsification de requêtes intersites. Étant donné que votre redirect_uri peut être deviné, l'utilisation d'une valeur state peut vous assurer qu'une connexion entrante est le résultat d'une requête d'authentification. Si vous générez une chaîne aléatoire ou encodez le hachage d'un cookie ou d'une autre valeur qui capture l'état du client, vous pouvez valider la réponse pour vous assurer en outre que la requête et la réponse proviennent du même navigateur, ce qui vous protège contre les attaques telles que la falsification de requêtes intersites. Consultez la documentation OpenID Connect pour savoir comment créer et confirmer un jeton state.

include_granted_scopes Optional

Permet aux applications d'utiliser l'autorisation incrémentielle pour demander l'accès à des champs d'application supplémentaires en contexte. Si vous définissez la valeur de ce paramètre sur true et que la requête d'autorisation est accordée, le nouveau jeton d'accès couvrira également tous les champs d'application auxquels l'utilisateur a précédemment accordé l'accès à l'application. Pour obtenir des exemples, consultez la section Autorisation incrémentielle.

login_hint Optional

Si votre application sait quel utilisateur tente de s'authentifier, elle peut utiliser ce paramètre pour fournir un indice au serveur d'authentification Google. Le serveur utilise l'indice pour simplifier le flux de connexion en préremplissant le champ d'adresse e-mail dans le formulaire de connexion ou en sélectionnant la session multiconnexion appropriée.

Définissez la valeur du paramètre sur une adresse e-mail ou un identifiant sub, qui est équivalent à l'ID Google de l'utilisateur.

prompt Optional

Liste d'invites à présenter à l'utilisateur, délimitée par des espaces et sensible à la casse. Si vous ne spécifiez pas ce paramètre, l'utilisateur ne sera invité qu'à la première fois que votre projet demandera l'accès. Pour en savoir plus, consultez la section Demander un nouveau consentement.

Les valeurs possibles sont :

none N'affichez aucun écran d'authentification ni d'autorisation. Ne doit pas être spécifié avec d'autres valeurs.
consent Demandez à l'utilisateur de donner son consentement.
select_account Invitez l'utilisateur à sélectionner un compte.

Exemple de redirection vers le serveur d'autorisation de Google

Vous trouverez ci-dessous un exemple d'URL, avec des sauts de ligne et des espaces pour une meilleure lisibilité.

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly%20https%3A//www.googleapis.com/auth/calendar.readonly&
 include_granted_scopes=true&
 response_type=token&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

Une fois l'URL de la requête créée, redirigez-y l'utilisateur.

Exemple de code JavaScript

L'extrait JavaScript suivant montre comment lancer le flux d'autorisation en JavaScript sans utiliser la bibliothèque cliente des API Google pour JavaScript. Étant donné que ce point de terminaison OAuth 2.0 n'est pas compatible avec le partage de ressources entre origines (CORS), l'extrait crée un formulaire qui ouvre la requête vers ce point de terminaison.

/*
 * Create form to request access token from Google's OAuth 2.0 server.
 */
function oauthSignIn() {
  // Google's OAuth 2.0 endpoint for requesting an access token
  var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';

  // Create <form> element to submit parameters to OAuth 2.0 endpoint.
  var form = document.createElement('form');
  form.setAttribute('method', 'GET'); // Send as a GET request.
  form.setAttribute('action', oauth2Endpoint);

  // Parameters to pass to OAuth 2.0 endpoint.
  var params = {'client_id': 'YOUR_CLIENT_ID',
                'redirect_uri': 'YOUR_REDIRECT_URI',
                'response_type': 'token',
                'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly',
                'include_granted_scopes': 'true',
                'state': 'pass-through value'};

  // Add form parameters as hidden input values.
  for (var p in params) {
    var input = document.createElement('input');
    input.setAttribute('type', 'hidden');
    input.setAttribute('name', p);
    input.setAttribute('value', params[p]);
    form.appendChild(input);
  }

  // Add form to page and submit it to open the OAuth 2.0 endpoint.
  document.body.appendChild(form);
  form.submit();
}

Étape 2: Google demande à l'utilisateur son consentement

À cette étape, l'utilisateur décide d'accorder ou non l'accès demandé à votre application. À ce stade, Google affiche une fenêtre de consentement indiquant le nom de votre application et les services de l'API Google auxquels il demande l'autorisation d'accéder à l'aide des identifiants de l'utilisateur, ainsi qu'un récapitulatif des niveaux d'accès à accorder. L'utilisateur peut alors accepter d'accorder l'accès à un ou plusieurs champs d'application demandés par votre application ou refuser la requête.

À ce stade, votre application n'a rien à faire, car elle attend la réponse du serveur OAuth 2.0 de Google indiquant si un accès a été accordé. Cette réponse est expliquée à l'étape suivante.

Erreurs

Les requêtes adressées au point de terminaison d'autorisation OAuth 2.0 de Google peuvent afficher des messages d'erreur destinés aux utilisateurs au lieu des flux d'authentification et d'autorisation attendus. Vous trouverez ci-dessous les codes d'erreur courants et les solutions suggérées.

admin_policy_enforced

Le compte Google ne peut pas autoriser un ou plusieurs champs d'application demandés en raison des règles de son administrateur Google Workspace. Pour en savoir plus sur la façon dont un administrateur peut restreindre l'accès à tous les champs d'application ou à des champs d'application sensibles et limités jusqu'à ce que l'accès soit explicitement accordé à votre ID client OAuth, consultez l'article d'aide pour les administrateurs Google Workspace Contrôler l'accès des applications tierces et internes aux données Google Workspace.

disallowed_useragent

Le point de terminaison d'autorisation s'affiche dans un user-agent intégré non autorisé par les Règles OAuth 2.0 de Google.

Android

Les développeurs Android peuvent rencontrer ce message d'erreur lorsqu'ils ouvrent des requêtes d'autorisation dans android.webkit.WebView. Les développeurs doivent plutôt utiliser des bibliothèques Android telles que Google Sign-In pour Android ou AppAuth pour Android de l'OpenID Foundation.

Les développeurs Web peuvent rencontrer cette erreur lorsqu'une application Android ouvre un lien Web général dans un user-agent intégré et qu'un utilisateur accède au point de terminaison d'autorisation OAuth 2.0 de Google depuis votre site. Les développeurs doivent autoriser les liens généraux à s'ouvrir dans le gestionnaire de liens par défaut du système d'exploitation, qui inclut à la fois les gestionnaires de Android App Links et l'application de navigateur par défaut. La bibliothèque Android Custom Tabs est également une option compatible.

iOS

Les développeurs iOS et macOS peuvent rencontrer cette erreur lorsqu'ils ouvrent des demandes d'autorisation dans WKWebView. Les développeurs doivent plutôt utiliser des bibliothèques iOS telles que Google Sign-In pour iOS ou AppAuth pour iOS de l'OpenID Foundation.

Les développeurs Web peuvent rencontrer cette erreur lorsqu'une application iOS ou macOS ouvre un lien Web général dans un user-agent intégré et qu'un utilisateur accède au point de terminaison d'autorisation OAuth 2.0 de Google depuis votre site. Les développeurs doivent autoriser les liens généraux à s'ouvrir dans le gestionnaire de liens par défaut du système d'exploitation, qui inclut à la fois les gestionnaires Universal Links et l'application de navigateur par défaut. La bibliothèque SFSafariViewController est également une option compatible.

org_internal

L'ID client OAuth de la requête fait partie d'un projet limitant l'accès aux comptes Google dans une organisation Google Cloud spécifique. Pour en savoir plus sur cette option de configuration, consultez la section Type d'utilisateur dans l'article d'aide "Configurer votre écran de consentement OAuth".

invalid_client

L'origine de la requête n'est pas autorisée pour ce client. Consultez origin_mismatch.

invalid_grant

Lorsque vous utilisez l'autorisation incrémentielle, le jeton peut avoir expiré ou avoir été invalidé. Réauthentifiez l'utilisateur et demandez-lui son consentement pour obtenir de nouveaux jetons. Si cette erreur persiste, assurez-vous que votre application a été correctement configurée et que vous utilisez les jetons et les paramètres appropriés dans votre requête. Sinon, le compte utilisateur a peut-être été supprimé ou désactivé.

origin_mismatch

Le schéma, le domaine et/ou le port du code JavaScript à l'origine de la requête d'autorisation peuvent ne pas correspondre à un URI d'origine JavaScript autorisé enregistré pour l'ID client OAuth. Vérifiez les origines JavaScript autorisées dans la Google API Console Credentials page.

redirect_uri_mismatch

L'redirect_uri transmis dans la requête d'autorisation ne correspond pas à un URI de redirection autorisé pour l'ID client OAuth. Examinez les URI de redirection autorisés dans le fichier Google API Console Credentials page.

Le schéma, le domaine et/ou le port du code JavaScript à l'origine de la requête d'autorisation peuvent ne pas correspondre à un URI d'origine JavaScript autorisé enregistré pour l'ID client OAuth. Vérifiez les origines JavaScript autorisées dans Google API Console Credentials page.

Le paramètre redirect_uri peut faire référence au flux OAuth hors bande (OOB) qui a été abandonné et n'est plus pris en charge. Consultez le guide de migration pour mettre à jour votre intégration.

invalid_request

Votre demande ne correspond pas aux critères requis. Plusieurs raisons peuvent expliquer ce problème:

  • La requête n'était pas correctement formatée
  • Des paramètres obligatoires manquaient dans la requête.
  • La requête utilise une méthode d'autorisation non acceptée par Google. Vérifier que votre intégration OAuth utilise une méthode d'intégration recommandée

Étape 3: Gérer la réponse du serveur OAuth 2.0

Points de terminaison OAuth 2.0

Le serveur OAuth 2.0 envoie une réponse à l'redirect_uri spécifié dans votre requête de jeton d'accès.

Si l'utilisateur approuve la requête, la réponse contient un jeton d'accès. Si l'utilisateur n'approuve pas la requête, la réponse contient un message d'erreur. Le jeton d'accès ou le message d'erreur est renvoyé dans le fragment de hachage de l'URI de redirection, comme illustré ci-dessous:

  • Réponse d'un jeton d'accès:

    https://oauth2.example.com/callback#access_token=4/P7q7W91&token_type=Bearer&expires_in=3600

    En plus du paramètre access_token, la chaîne de fragment contient également le paramètre token_type, qui est toujours défini sur Bearer, et le paramètre expires_in, qui spécifie la durée de vie du jeton, en secondes. Si le paramètre state a été spécifié dans la requête de jeton d'accès, sa valeur est également incluse dans la réponse.

  • Réponse d'erreur:
    https://oauth2.example.com/callback#error=access_denied

Exemple de réponse du serveur OAuth 2.0

Vous pouvez tester ce flux en cliquant sur l'exemple d'URL suivant, qui demande un accès en lecture seule pour afficher les métadonnées des fichiers de votre compte Google Drive et un accès en lecture seule pour afficher vos événements Google Agenda:

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly%20https%3A//www.googleapis.com/auth/calendar.readonly&
 include_granted_scopes=true&
 response_type=token&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

Une fois le flux OAuth 2.0 terminé, vous serez redirigé vers http://localhost/oauth2callback. Cette URL génère une erreur 404 NOT FOUND, sauf si votre machine locale diffuse un fichier à cette adresse. L'étape suivante fournit plus d'informations sur les informations renvoyées dans l'URI lorsque l'utilisateur est redirigé vers votre application.

Étape 4: Vérifiez les autorisations accordées par les utilisateurs

Lorsque vous demandez plusieurs niveaux d'accès à la fois, les utilisateurs peuvent ne pas accorder tous les niveaux d'accès demandés par votre application. Votre application doit toujours vérifier les autorisations accordées par l'utilisateur et gérer tout refus d'autorisation en désactivant les fonctionnalités concernées. Pour en savoir plus, consultez Gérer les autorisations précises.

Points de terminaison OAuth 2.0

Pour vérifier si l'utilisateur a accordé à votre application l'accès à un champ d'application particulier, examinez le champ scope dans la réponse du jeton d'accès. Champs d'application d'accès accordés par le jeton d'accès, exprimés sous la forme d'une liste de chaînes sensibles à la casse, délimitées par des espaces.

Par exemple, l'exemple de réponse du jeton d'accès suivant indique que l'utilisateur a accordé à votre application l'accès aux autorisations d'activité Drive en lecture seule et aux événements Agenda:

  {
    "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
    "expires_in": 3920,
    "token_type": "Bearer",
    "scope": "https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly",
    "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
  }

Appeler des API Google

Points de terminaison OAuth 2.0

Une fois que votre application a obtenu un jeton d'accès, vous pouvez l'utiliser pour effectuer des appels à une API Google au nom d'un compte utilisateur donné si le ou les champs d'application de l'accès requis par l'API ont été accordés. Pour ce faire, incluez le jeton d'accès dans une requête envoyée à l'API en incluant un paramètre de requête access_token ou une valeur Bearer d'en-tête HTTP Authorization. Lorsque c'est possible, l'en-tête HTTP est préférable, car les chaînes de requête ont tendance à être visibles dans les journaux du serveur. Dans la plupart des cas, vous pouvez utiliser une bibliothèque cliente pour configurer vos appels aux API Google (par exemple, lorsque vous appelez l'API Drive Files).

Vous pouvez tester toutes les API Google et consulter leurs champs d'application sur OAuth 2.0 Playground.

Exemples de requêtes HTTP GET

Un appel au point de terminaison drive.files (API Drive Files) à l'aide de l'en-tête HTTP Authorization: Bearer peut se présenter comme suit. Notez que vous devez spécifier votre propre jeton d'accès:

GET /drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token

Voici un appel à la même API pour l'utilisateur authentifié à l'aide du paramètre de chaîne de requête access_token:

GET https://www.googleapis.com/drive/v2/files?access_token=access_token

curl exemples

Vous pouvez tester ces commandes avec l'application de ligne de commande curl. Voici un exemple qui utilise l'option d'en-tête HTTP (recommandée):

curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files

Vous pouvez également utiliser l'option de paramètre de chaîne de requête:

curl https://www.googleapis.com/drive/v2/files?access_token=access_token

Exemple de code JavaScript

L'extrait de code ci-dessous montre comment utiliser le partage de ressources entre origines (CORS) pour envoyer une requête à une API Google. Cet exemple n'utilise pas la bibliothèque cliente des API Google pour JavaScript. Toutefois, même si vous n'utilisez pas la bibliothèque cliente, le guide de compatibilité avec CORS de la documentation de cette bibliothèque vous aidera probablement à mieux comprendre ces requêtes.

Dans cet extrait de code, la variable access_token représente le jeton que vous avez obtenu pour envoyer des requêtes API au nom de l'utilisateur autorisé. L'exemple complet montre comment stocker ce jeton dans l'espace de stockage local du navigateur et le récupérer lors de l'envoi d'une requête API.

var xhr = new XMLHttpRequest();
xhr.open('GET',
    'https://www.googleapis.com/drive/v3/about?fields=user&' +
    'access_token=' + params['access_token']);
xhr.onreadystatechange = function (e) {
  console.log(xhr.response);
};
xhr.send(null);

Exemple complet

Points de terminaison OAuth 2.0

Cet exemple de code montre comment effectuer le flux OAuth 2.0 en JavaScript sans utiliser la bibliothèque cliente des API Google pour JavaScript. Le code est destiné à une page HTML qui affiche un bouton permettant d'essayer une requête API. Si vous cliquez sur le bouton, le code vérifie si la page a stocké un jeton d'accès à l'API dans l'espace de stockage local de votre navigateur. Si c'est le cas, il exécute la requête API. Sinon, il lance le flux OAuth 2.0.

Pour le flux OAuth 2.0, la page suit ces étapes:

  1. Il redirige l'utilisateur vers le serveur OAuth 2.0 de Google, qui demande l'accès aux habilitations https://www.googleapis.com/auth/drive.metadata.readonly et https://www.googleapis.com/auth/calendar.readonly.
  2. Après avoir accordé (ou refusé) l'accès à un ou plusieurs champs d'application demandés, l'utilisateur est redirigé vers la page d'origine, qui analyse le jeton d'accès à partir de la chaîne d'identifiant de fragment.
  3. La page vérifie les autorisations que l'utilisateur a accordées à l'application.
  4. Si l'utilisateur a accordé l'accès aux champs d'application demandés, la page utilise le jeton d'accès pour envoyer l'exemple de requête API.

    La requête d'API appelle la méthode about.get de l'API Drive pour récupérer des informations sur le compte Google Drive de l'utilisateur autorisé.

  5. Si la requête s'exécute correctement, la réponse de l'API est enregistrée dans la console de débogage du navigateur.

Vous pouvez révoquer l'accès à l'application sur la page Autorisations de votre compte Google. L'application sera listée sous le nom Démo OAuth 2.0 pour la documentation des API Google.

Pour exécuter ce code localement, vous devez définir des valeurs pour les variables YOUR_CLIENT_ID et YOUR_REDIRECT_URI qui correspondent à vos identifiants d'autorisation. La variable YOUR_REDIRECT_URI doit être définie sur la même URL que celle de la page diffusée. La valeur doit correspondre exactement à l'un des URI de redirection autorisés pour le client OAuth 2.0, que vous avez configuré dans API Console Credentials page. Si cette valeur ne correspond pas à un URI autorisé, une erreur redirect_uri_mismatch s'affiche. Votre projet doit également avoir activé l'API appropriée pour cette requête.

<html><head></head><body>
<script>
  var YOUR_CLIENT_ID = 'REPLACE_THIS_VALUE';
  var YOUR_REDIRECT_URI = 'REPLACE_THIS_VALUE';

  // Parse query string to see if page request is coming from OAuth 2.0 server.
  var fragmentString = location.hash.substring(1);
  var params = {};
  var regex = /([^&=]+)=([^&]*)/g, m;
  while (m = regex.exec(fragmentString)) {
    params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
  }
  if (Object.keys(params).length > 0 && params['state']) {
    if (params['state'] == localStorage.getItem('state')) {
      localStorage.setItem('oauth2-test-params', JSON.stringify(params) );

      trySampleRequest();
    } else {
      console.log('State mismatch. Possible CSRF attack');
    }
  }

  // Function to generate a random state value
  function generateCryptoRandomState() {
    const randomValues = new Uint32Array(2);
    window.crypto.getRandomValues(randomValues);

    // Encode as UTF-8
    const utf8Encoder = new TextEncoder();
    const utf8Array = utf8Encoder.encode(
      String.fromCharCode.apply(null, randomValues)
    );

    // Base64 encode the UTF-8 data
    return btoa(String.fromCharCode.apply(null, utf8Array))
      .replace(/\+/g, '-')
      .replace(/\//g, '_')
      .replace(/=+$/, '');
  }

  // If there's an access token, try an API request.
  // Otherwise, start OAuth 2.0 flow.
  function trySampleRequest() {
    var params = JSON.parse(localStorage.getItem('oauth2-test-params'));
    if (params && params['access_token']) { 
      // User authorized the request. Now, check which scopes were granted.
      if (params['scope'].includes('https://www.googleapis.com/auth/drive.metadata.readonly')) {
        // User authorized read-only Drive activity permission.
        // Calling the APIs, etc.
        var xhr = new XMLHttpRequest();
        xhr.open('GET',
          'https://www.googleapis.com/drive/v3/about?fields=user&' +
          'access_token=' + params['access_token']);
        xhr.onreadystatechange = function (e) {
          if (xhr.readyState === 4 && xhr.status === 200) {
            console.log(xhr.response);
          } else if (xhr.readyState === 4 && xhr.status === 401) {
            // Token invalid, so prompt for user permission.
            oauth2SignIn();
          }
        };
        xhr.send(null);
      }
      else {
        // User didn't authorize read-only Drive activity permission.
        // Update UX and application accordingly
        console.log('User did not authorize read-only Drive activity permission.');
      }

      // Check if user authorized Calendar read permission.
      if (params['scope'].includes('https://www.googleapis.com/auth/calendar.readonly')) {
        // User authorized Calendar read permission.
        // Calling the APIs, etc.
        console.log('User authorized Calendar read permission.');
      }
      else {
        // User didn't authorize Calendar read permission.
        // Update UX and application accordingly
        console.log('User did not authorize Calendar read permission.');
      } 
    } else {
      oauth2SignIn();
    }
  }

  /*
   * Create form to request access token from Google's OAuth 2.0 server.
   */
  function oauth2SignIn() {
    // create random state value and store in local storage
    var state = generateCryptoRandomState();
    localStorage.setItem('state', state);

    // Google's OAuth 2.0 endpoint for requesting an access token
    var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';

    // Create element to open OAuth 2.0 endpoint in new window.
    var form = document.createElement('form');
    form.setAttribute('method', 'GET'); // Send as a GET request.
    form.setAttribute('action', oauth2Endpoint);

    // Parameters to pass to OAuth 2.0 endpoint.
    var params = {'client_id': YOUR_CLIENT_ID,
                  'redirect_uri': YOUR_REDIRECT_URI,
                  'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly',
                  'state': state,
                  'include_granted_scopes': 'true',
                  'response_type': 'token'};

    // Add form parameters as hidden input values.
    for (var p in params) {
      var input = document.createElement('input');
      input.setAttribute('type', 'hidden');
      input.setAttribute('name', p);
      input.setAttribute('value', params[p]);
      form.appendChild(input);
    }

    // Add form to page and submit it to open the OAuth 2.0 endpoint.
    document.body.appendChild(form);
    form.submit();
  }
</script>

<button onclick="trySampleRequest();">Try sample request</button>
</body></html>

Règles de validation des origines JavaScript

Google applique les règles de validation suivantes aux origines JavaScript afin d'aider les développeurs à sécuriser leurs applications. Vos origines JavaScript doivent respecter ces règles. Consultez la section 3 de la RFC 3986 pour connaître la définition des termes "domaine", "hôte" et "schéma", mentionnés ci-dessous.

Règles de validation
Schéma

Les origines JavaScript doivent utiliser le schéma HTTPS, et non HTTP. Les URI localhost (y compris les URI d'adresse IP localhost) sont exemptés de cette règle.

Hôte

Les hôtes ne peuvent pas être des adresses IP brutes. Les adresses IP de l'hôte local sont exclues de cette règle.

Domaine
  • Les domaines de premier niveau (top-level domain) hôtes doivent appartenir à la liste des suffixes publics.
  • Les domaines d'hôte ne peuvent pas être “googleusercontent.com”.
  • Les origines JavaScript ne peuvent pas contenir de domaines de raccourcisseur d'URL (par exemple, goo.gl) sauf si l'application en est propriétaire.
  • Userinfo

    Les origines JavaScript ne peuvent pas contenir le sous-composant userinfo.

    Chemin d'accès

    Les origines JavaScript ne peuvent pas contenir le composant de chemin d'accès.

    Query

    Les origines JavaScript ne peuvent pas contenir le composant de requête.

    Fragment

    Les origines JavaScript ne peuvent pas contenir le composant de fragment.

    Caractères Les origines JavaScript ne peuvent pas contenir certains caractères, y compris les suivants :
    • Caractères génériques ('*')
    • Caractères ASCII non imprimables
    • Encodages en pourcentage non valides (tout encodage en pourcentage qui ne suit pas le format d'encodage en URL, à savoir un signe de pourcentage suivi de deux chiffres hexadécimaux)
    • Caractères nuls (un caractère NULL encodé, par exemple, %00, %C0%80)

    Autorisation incrémentielle

    Dans le protocole OAuth 2.0, votre application demande une autorisation pour accéder aux ressources, qui sont identifiées par des champs d'application. Il est considéré comme une bonne pratique d'expérience utilisateur de demander l'autorisation pour les ressources au moment où vous en avez besoin. Pour permettre cette pratique, le serveur d'autorisation de Google est compatible avec l'autorisation incrémentielle. Cette fonctionnalité vous permet de demander des portées au fur et à mesure que vous en avez besoin. Si l'utilisateur accorde l'autorisation pour la nouvelle portée, elle renvoie un code d'autorisation pouvant être échangé contre un jeton contenant toutes les portées que l'utilisateur a accordées au projet.

    Par exemple, une application qui permet aux utilisateurs d'échantillonner des titres musicaux et de créer des mixages peut nécessiter très peu de ressources au moment de la connexion, peut-être rien de plus que le nom de la personne qui se connecte. Toutefois, l'enregistrement d'un mix terminé nécessiterait un accès à son compte Google Drive. La plupart des utilisateurs trouveraient naturel que l'accès à leur compte Google Drive ne leur soit demandé que lorsque l'application en a réellement besoin.

    Dans ce cas, au moment de la connexion, l'application peut demander les habilitations openid et profile pour effectuer une connexion de base, puis demander ultérieurement l'habilitation https://www.googleapis.com/auth/drive.file au moment de la première requête pour enregistrer un mix.

    Les règles suivantes s'appliquent à un jeton d'accès obtenu à partir d'une autorisation incrémentielle:

    • Le jeton peut être utilisé pour accéder aux ressources correspondant à l'un des champs d'application intégrés à la nouvelle autorisation combinée.
    • Lorsque vous utilisez le jeton d'actualisation pour l'autorisation combinée afin d'obtenir un jeton d'accès, le jeton d'accès représente l'autorisation combinée et peut être utilisé pour toutes les valeurs scope incluses dans la réponse.
    • L'autorisation combinée inclut tous les champs d'application que l'utilisateur a accordés au projet d'API, même si les autorisations ont été demandées par différents clients. Par exemple, si un utilisateur a accordé l'accès à un champ d'application à l'aide du client pour ordinateur de bureau de l'application, puis accordé un autre champ à la même application via un client mobile, l'autorisation combinée inclura les deux champs.
    • Si vous révoquez un jeton représentant une autorisation combinée, l'accès à tous les champs d'application de cette autorisation au nom de l'utilisateur associé est révoqué simultanément.

    Les exemples de code ci-dessous montrent comment ajouter des portées à un jeton d'accès existant. Cette approche permet à votre application d'éviter de gérer plusieurs jetons d'accès.

    Points de terminaison OAuth 2.0

    Pour ajouter des habilitations à un jeton d'accès existant, incluez le paramètre include_granted_scopes dans votre requête adressée au serveur OAuth 2.0 de Google.

    L'extrait de code suivant montre comment procéder. L'extrait suppose que vous avez stocké les portées pour lesquelles votre jeton d'accès est valide dans l'espace de stockage local du navigateur. (Le code de l'exemple complet stocke une liste des champs d'application pour lesquels le jeton d'accès est valide en définissant la propriété oauth2-test-params.scope dans l'espace de stockage local du navigateur.)

    L'extrait compare les champs d'application pour lesquels le jeton d'accès est valide au champ d'application que vous souhaitez utiliser pour une requête particulière. Si le jeton d'accès ne couvre pas ce champ d'application, le flux OAuth 2.0 commence. Ici, la fonction oauth2SignIn est identique à celle fournie à l'étape 2 (et qui est fournie plus tard dans l'exemple complet).

    var SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly';
    var params = JSON.parse(localStorage.getItem('oauth2-test-params'));
    
    var current_scope_granted = false;
    if (params.hasOwnProperty('scope')) {
      var scopes = params['scope'].split(' ');
      for (var s = 0; s < scopes.length; s++) {
        if (SCOPE == scopes[s]) {
          current_scope_granted = true;
        }
      }
    }
    
    if (!current_scope_granted) {
      oauth2SignIn(); // This function is defined elsewhere in this document.
    } else {
      // Since you already have access, you can proceed with the API request.
    }

    Révoquer un jeton

    Dans certains cas, un utilisateur peut souhaiter révoquer l'accès accordé à une application. Un utilisateur peut révoquer l'accès en accédant aux paramètres du compte. Pour en savoir plus, consultez la section Supprimer l'accès d'une application ou d'un site du document d'aide "Applications et sites tiers ayant accès à votre compte".

    Une application peut également révoquer de manière programmatique l'accès qui lui a été accordé. La révocation programmatique est importante dans les cas où un utilisateur se désinscrit, supprime une application ou que les ressources d'API requises par une application ont changé de manière significative. En d'autres termes, une partie du processus de suppression peut inclure une requête d'API pour s'assurer que les autorisations précédemment accordées à l'application sont supprimées.

    Points de terminaison OAuth 2.0

    Pour révoquer un jeton de manière programmatique, votre application envoie une requête à https://oauth2.googleapis.com/revoke et inclut le jeton en tant que paramètre:

    curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \
            https://oauth2.googleapis.com/revoke?token={token}

    Il peut s'agir d'un jeton d'accès ou d'un jeton d'actualisation. Si le jeton est un jeton d'accès et qu'il dispose d'un jeton d'actualisation correspondant, le jeton d'actualisation est également révoqué.

    Si la révocation est traitée avec succès, le code d'état HTTP de la réponse est 200. Pour les conditions d'erreur, un code d'état HTTP 400 est renvoyé avec un code d'erreur.

    L'extrait de code JavaScript suivant montre comment révoquer un jeton en JavaScript sans utiliser la bibliothèque cliente des API Google pour JavaScript. Étant donné que le point de terminaison OAuth 2.0 de Google pour la révocation des jetons n'est pas compatible avec le partage de ressources inter-origines (CORS), le code crée un formulaire et l'envoie au point de terminaison au lieu d'utiliser la méthode XMLHttpRequest() pour publier la requête.

    function revokeAccess(accessToken) {
      // Google's OAuth 2.0 endpoint for revoking access tokens.
      var revokeTokenEndpoint = 'https://oauth2.googleapis.com/revoke';
    
      // Create <form> element to use to POST data to the OAuth 2.0 endpoint.
      var form = document.createElement('form');
      form.setAttribute('method', 'post');
      form.setAttribute('action', revokeTokenEndpoint);
    
      // Add access token to the form so it is set as value of 'token' parameter.
      // This corresponds to the sample curl request, where the URL is:
      //      https://oauth2.googleapis.com/revoke?token={token}
      var tokenField = document.createElement('input');
      tokenField.setAttribute('type', 'hidden');
      tokenField.setAttribute('name', 'token');
      tokenField.setAttribute('value', accessToken);
      form.appendChild(tokenField);
    
      // Add form to page and submit it to actually revoke the token.
      document.body.appendChild(form);
      form.submit();
    }

    Implémenter la protection multicompte

    Pour protéger les comptes de vos utilisateurs, vous devez également implémenter la protection multicompte à l'aide du service de protection multicompte de Google. Ce service vous permet de vous abonner à des notifications d'événements de sécurité qui fournissent des informations à votre application sur les modifications majeures apportées au compte utilisateur. Vous pouvez ensuite utiliser ces informations pour prendre des mesures en fonction de la façon dont vous décidez de répondre aux événements.

    Voici quelques exemples de types d'événements envoyés à votre application par le service de protection multicompte de Google:

    • https://schemas.openid.net/secevent/risc/event-type/sessions-revoked
    • https://schemas.openid.net/secevent/oauth/event-type/token-revoked
    • https://schemas.openid.net/secevent/risc/event-type/account-disabled

    Pour en savoir plus sur l'implémentation de la Protection multicompte et obtenir la liste complète des événements disponibles, consultez la page Protéger les comptes utilisateur avec la Protection multicompte .