Utiliser le modèle de jeton

La bibliothèque JavaScript google.accounts.oauth2 vous aide à demander le consentement de l'utilisateur et à obtenir un jeton d'accès pour utiliser les données utilisateur. Elle est basée sur le flux d'octroi implicite OAuth 2.0 et conçue pour vous permettre d'appeler directement les API Google à l'aide de REST et de CORS, ou d'utiliser notre bibliothèque cliente des API Google pour JavaScript (également appelée gapi.client) pour un accès simple et flexible à nos API plus complexes.

Avant d'accéder aux données utilisateur protégées depuis un navigateur, les utilisateurs de votre site déclenchent les processus de sélection de compte, de connexion et de consentement basés sur le Web de Google. Enfin, les serveurs OAuth de Google émettent et renvoient un jeton d'accès à votre application Web.

Dans le modèle d'autorisation basé sur les jetons, il n'est pas nécessaire de stocker les jetons d'actualisation par utilisateur sur votre serveur backend.

Nous vous recommandons de suivre l'approche décrite ici plutôt que les techniques abordées dans l'ancien guide OAuth 2.0 pour les applications Web côté client.

Prérequis

Suivez les étapes décrites dans Configuration pour configurer votre écran de consentement OAuth, obtenir un ID client et charger la bibliothèque cliente.

Initialiser un client de jetons

Appelez initTokenClient() pour initialiser un nouveau client de jeton avec l'ID client de votre application Web. Vous devez inclure une liste d'un ou plusieurs scopes auxquels l'utilisateur doit accéder :

const client = google.accounts.oauth2.initTokenClient({
  client_id: 'YOUR_GOOGLE_CLIENT_ID',
  scope: 'https://www.googleapis.com/auth/calendar.readonly',
  callback: (response) => {
    ...
  },
});

Déclencher le flux de jetons OAuth 2.0

Utilisez la méthode requestAccessToken() pour déclencher le flux d'expérience utilisateur du jeton et obtenir un jeton d'accès. Google invite l'utilisateur à :

  • Sélectionnez son compte.
  • connectez-vous au compte Google si ce n'est pas déjà fait.
  • donner votre consentement pour que votre application Web accède à chaque champ d'application demandé.

Un geste de l'utilisateur déclenche le flux de jetons : <button onclick="client.requestAccessToken();">Authorize me</button>

Google renvoie ensuite un TokenResponse contenant un jeton d'accès et la liste des autorisations accordées par l'utilisateur, ou une erreur, à votre gestionnaire de rappel.

Les utilisateurs peuvent fermer le sélecteur de compte ou les fenêtres de connexion. Dans ce cas, votre fonction de rappel ne sera pas appelée.

La conception et l'expérience utilisateur de votre application ne doivent être implémentées qu'après un examen approfondi des Règles OAuth 2.0 de Google. Ces règles couvrent l'utilisation de plusieurs portées, le moment et la manière de gérer le consentement de l'utilisateur, et plus encore.

L'autorisation incrémentielle est une méthodologie de conception de règles et d'applications utilisée pour demander l'accès aux ressources, à l'aide de portées, uniquement en cas de besoin plutôt qu'à l'avance et en une seule fois. Les utilisateurs peuvent autoriser ou refuser le partage des ressources individuelles demandées par votre application. C'est ce qu'on appelle les autorisations précises.

Au cours de ce processus, Google demande le consentement de l'utilisateur, en listant individuellement chaque champ d'application demandé. Les utilisateurs sélectionnent les ressources à partager avec votre application. Enfin, Google appelle votre fonction de rappel pour renvoyer un jeton d'accès et les champs d'application approuvés par l'utilisateur. Votre application gère ensuite en toute sécurité les différents résultats possibles avec des autorisations précises.

Il existe toutefois des exceptions. Les applications Google Workspace Enterprise avec délégation d'autorité au niveau du domaine ou les applications marquées comme fiables contournent l'écran de consentement pour les autorisations précises. Pour ces applications, les utilisateurs ne verront pas l'écran de consentement pour les autorisations précises. Votre application recevra tous les niveaux d'accès demandés ou aucun.

Pour en savoir plus, consultez Gérer les autorisations précises.

Autorisation incrémentielle

Pour les applications Web, les deux scénarios généraux suivants illustrent l'autorisation incrémentielle à l'aide de :

  • Application Ajax monopage, utilisant souvent XMLHttpRequest avec un accès dynamique aux ressources.
  • Plusieurs pages Web : les ressources sont séparées et gérées page par page.

Ces deux scénarios sont présentés pour illustrer les considérations et les méthodologies de conception, mais ne sont pas destinés à être des recommandations exhaustives sur la façon d'intégrer le consentement dans votre application. Les applications réelles peuvent utiliser une variante ou une combinaison de ces techniques.

Ajax

Ajoutez la prise en charge de l'autorisation incrémentielle à votre application en effectuant plusieurs appels à requestAccessToken() et en utilisant le paramètre scope de l'objet OverridableTokenClientConfig pour demander des niveaux d'accès individuels au moment où ils sont nécessaires et uniquement lorsque cela est nécessaire. Dans cet exemple, les ressources ne seront demandées et visibles qu'après qu'un geste de l'utilisateur a développé une section de contenu réduite.

Application Ajax
Initialisez le client de jetons lors du chargement de la page :
        const client = google.accounts.oauth2.initTokenClient({
          client_id: 'YOUR_GOOGLE_CLIENT_ID',
          callback: "onTokenResponse",
        });
      
Demandez le consentement et obtenez des jetons d'accès grâce aux gestes de l'utilisateur. Cliquez sur "+" pour ouvrir :

Documents à lire

Afficher les documents récents

          client.requestAccessToken(
            overrideConfig = ({
               scope = 'https://www.googleapis.com/auth/documents.readonly'
             })
           );
        

Événements à venir

Afficher les informations de l'agenda

          client.requestAccessToken(
            overrideConfig = ({
               scope = 'https://www.googleapis.com/auth/calendar.readonly'
             })
           );
        

Afficher des photos

          client.requestAccessToken(
            overrideConfig = ({
               scope = 'https://www.googleapis.com/auth/photoslibrary.readonly'
             })
           );
        

Chaque appel à requestAccessToken déclenche un moment de consentement de l'utilisateur. Votre application n'aura accès qu'aux ressources requises par la section qu'un utilisateur choisit de développer, ce qui limite le partage de ressources par le choix de l'utilisateur.

Plusieurs pages Web

Lorsque vous concevez une autorisation incrémentielle, plusieurs pages sont utilisées pour demander uniquement le ou les niveaux d'accès requis pour charger une page. Cela réduit la complexité et la nécessité d'effectuer plusieurs appels pour obtenir le consentement de l'utilisateur et récupérer un jeton d'accès.

Application multipage
Page Web Code
Page 1. Documents à lire
  const client = google.accounts.oauth2.initTokenClient({
    client_id: 'YOUR_GOOGLE_CLIENT_ID',
    callback: "onTokenResponse",
    scope: 'https://www.googleapis.com/auth/documents.readonly',
  });
  client.requestAccessToken();
          
Page 2 : Événements à venir
  const client = google.accounts.oauth2.initTokenClient({
    client_id: 'YOUR_GOOGLE_CLIENT_ID',
    callback: "onTokenResponse",
    scope: 'https://www.googleapis.com/auth/calendar.readonly',
  });
  client.requestAccessToken();
          
Page 3. Carrousel de photos
  const client = google.accounts.oauth2.initTokenClient({
    client_id: 'YOUR_GOOGLE_CLIENT_ID',
    callback: "onTokenResponse",
    scope: 'https://www.googleapis.com/auth/photoslibrary.readonly',
  });
  client.requestAccessToken();
          

Chaque page demande le champ d'application nécessaire et obtient un jeton d'accès en appelant initTokenClient() et requestAccessToken() au moment du chargement. Dans ce scénario, des pages Web individuelles sont utilisées pour séparer clairement les fonctionnalités et les ressources utilisateur par portée. Dans une situation réelle, des pages individuelles peuvent demander plusieurs portées associées.

Autorisations précises

Les autorisations précises sont gérées de la même manière dans tous les scénarios. Une fois que requestAccessToken() a appelé votre fonction de rappel et qu'un jeton d'accès a été renvoyé, vérifiez que l'utilisateur a approuvé les niveaux d'accès demandés à l'aide de hasGrantedAllScopes() ou hasGrantedAnyScope(). Exemple :

const client = google.accounts.oauth2.initTokenClient({
  client_id: 'YOUR_GOOGLE_CLIENT_ID',
  scope: 'https://www.googleapis.com/auth/calendar.readonly \
          https://www.googleapis.com/auth/documents.readonly \
          https://www.googleapis.com/auth/photoslibrary.readonly',
  callback: (tokenResponse) => {
    if (tokenResponse && tokenResponse.access_token) {
      if (google.accounts.oauth2.hasGrantedAnyScope(tokenResponse,
          'https://www.googleapis.com/auth/photoslibrary.readonly')) {
        // Look at pictures
        ...
      }
      if (google.accounts.oauth2.hasGrantedAllScopes(tokenResponse,
          'https://www.googleapis.com/auth/calendar.readonly',
          'https://www.googleapis.com/auth/documents.readonly')) {
        // Meeting planning and review documents
        ...
      }
    }
  },
});

Toutes les autorisations précédemment acceptées lors de sessions ou de requêtes antérieures seront également incluses dans la réponse. Un enregistrement du consentement de l'utilisateur est conservé par utilisateur et par ID client. Il persiste sur plusieurs appels à initTokenClient() ou requestAccessToken(). Par défaut, le consentement de l'utilisateur n'est nécessaire que la première fois qu'il visite votre site Web et demande un nouveau champ d'application, mais il peut être demandé à chaque chargement de page à l'aide de prompt=consent dans les objets de configuration du client de jeton.

Utiliser des jetons

Dans le modèle de jeton, un jeton d'accès n'est pas stocké par l'OS ni par le navigateur. Au lieu de cela, un nouveau jeton est d'abord obtenu au moment du chargement de la page, ou ultérieurement en déclenchant un appel à requestAccessToken() par le biais d'un geste de l'utilisateur, comme l'appui sur un bouton.

Utiliser REST et CORS avec les API Google

Un jeton d'accès peut être utilisé pour envoyer des requêtes authentifiées aux API Google à l'aide de REST et de CORS. Cela permet aux utilisateurs de se connecter et de donner leur consentement, à Google d'émettre un jeton d'accès et à votre site de fonctionner avec les données des utilisateurs.

Dans cet exemple, affichez les événements à venir de l'utilisateur connecté à l'aide du jeton d'accès renvoyé par tokenRequest() :

var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://www.googleapis.com/calendar/v3/calendars/primary/events');
xhr.setRequestHeader('Authorization', 'Bearer ' + tokenResponse.access_token);
xhr.send();

Pour en savoir plus, consultez Utiliser CORS pour accéder aux API Google.

La section suivante explique comment s'intégrer facilement à des API plus complexes.

Utiliser la bibliothèque JavaScript des API Google

Le client de jetons fonctionne avec la bibliothèque cliente des API Google pour JavaScript. Consultez l'extrait de code ci-dessous.

const client = google.accounts.oauth2.initTokenClient({
  client_id: 'YOUR_GOOGLE_CLIENT_ID',
  scope: 'https://www.googleapis.com/auth/calendar.readonly',
  callback: (tokenResponse) => {
    if (tokenResponse && tokenResponse.access_token) {
      gapi.client.setApiKey('YOUR_API_KEY');
      gapi.client.load('calendar', 'v3', listUpcomingEvents);
    }
  },
});

function listUpcomingEvents() {
  gapi.client.calendar.events.list(...);
}

Expiration des jetons

De par leur conception, les jetons d'accès ont une durée de vie courte. Si le jeton d'accès expire avant la fin de la session de l'utilisateur, obtenez-en un nouveau en appelant requestAccessToken() à partir d'un événement déclenché par l'utilisateur, comme l'appui sur un bouton.

Appelez la méthode google.accounts.oauth2.revoke pour supprimer le consentement de l'utilisateur et l'accès aux ressources pour tous les niveaux d'accès accordés à votre application. Un jeton d'accès valide est requis pour révoquer cette autorisation :

google.accounts.oauth2.revoke('414a76cb127a7ece7ee4bf287602ca2b56f8fcbf7fcecc2cd4e0509268120bd7', done => {
    console.log(done);
    console.log(done.successful);
    console.log(done.error);
    console.log(done.error_description);
  });