Gérer les autorisations précises

Présentation

Grâce aux autorisations précises, les consommateurs peuvent contrôler plus précisément les données de compte qu'ils choisissent de partager avec chaque application. Elles sont bénéfiques à la fois pour les utilisateurs et les développeurs, car elles offrent plus de contrôle, de transparence et de sécurité. Ce guide vous aidera à comprendre les changements nécessaires et la marche à suivre pour mettre à jour vos applications afin qu'elles gèrent les autorisations précises.

Qu'est-ce qu'une autorisation précise ?

Imaginez que vous développiez une application de productivité qui demande à la fois les autorisations d'accès aux e-mails et à l'agenda. Vos utilisateurs peuvent souhaiter utiliser votre application uniquement pour Google Agenda, mais pas pour Gmail. Grâce aux autorisations OAuth précises, les utilisateurs peuvent choisir de n'accorder l'autorisation qu'à Google Agenda, mais pas à Gmail. En permettant aux utilisateurs d'accorder l'accès à des données spécifiques, cela minimise l'exposition des données, renforce la confiance et donne aux utilisateurs un contrôle axé sur la confidentialité de leur vie numérique. Il est important de concevoir votre application pour qu'elle puisse gérer de tels scénarios.

Lorsque plusieurs niveaux d'accès sans connexion sont demandés

Portées de connexion et de non-connexion

Pour les applications qui demandent à la fois des autorisations de connexion et des autorisations sans connexion, les utilisateurs voient d'abord la page d'autorisation pour les autorisations de connexion (email, profile et openid). Une fois que les utilisateurs ont autorisé le partage de leurs informations d'identité de base (nom, adresse e-mail et photo de profil), ils voient un écran d'autorisation précis pour les autorisations sans connexion. Dans ce cas, l'application doit vérifier les habilitations accordées par les utilisateurs et ne peut pas supposer que les utilisateurs accordent toutes les habilitations demandées. Dans l'exemple suivant, l'application Web demande les trois étendues de connexion et une étendue Google Drive sans connexion. Une fois que les utilisateurs ont accepté les niveaux d'accès à la connexion, l'écran de consentement aux autorisations précises s'affiche pour l'autorisation Google Drive :

Portées de connexion et de non-connexion

Plusieurs étendues sans connexion

Un écran de consentement détaillé s'affiche lorsque les applications demandent plusieurs autorisations autres que la connexion. Les utilisateurs peuvent sélectionner les autorisations qu'ils souhaitent accorder pour partager avec l'application. Voici un exemple d'écran de consentement pour des autorisations précises demandant l'accès aux messages Gmail et aux données Google Agenda de l'utilisateur :

Plusieurs étendues sans connexion

L'écran de consentement pour les autorisations précises ne s'applique pas aux applications qui ne demandent que des habilitations de connexion (email, profile et openid). Les utilisateurs approuvent ou refusent l'intégralité de la demande de connexion. En d'autres termes, si les applications ne demandent que des habilitations de connexion (une, deux ou les trois), l'écran d'autorisation d'accès précis n'est pas applicable.

L'écran de consentement pour les autorisations précises ne s'applique pas aux applications qui ne demandent qu'un seul champ d'application sans connexion. En d'autres termes, les utilisateurs approuvent ou refusent l'intégralité de la demande, et il n'y a pas de case à cocher sur l'écran de consentement. Le tableau suivant récapitule les cas où l'écran de consentement aux autorisations précises s'affiche.

Nombre de portées de connexion Nombre de niveaux d'accès sans connexion Écran de consentement pour les autorisations précises
1-3 0 Non applicable
1-3 1+ Applicable
0 1 Non applicable
0 2+ Applicable

Déterminer si vos applications sont concernées

Examinez attentivement toutes les sections de votre application dans lesquelles les points de terminaison d'autorisation Google OAuth 2.0 sont utilisés pour les demandes d'autorisation. Faites attention à celles qui demandent plusieurs habilitations, car elles activent des écrans de consentement pour les autorisations détaillées présentés aux utilisateurs. Dans ce cas, assurez-vous que votre code peut gérer le cas où les utilisateurs n'autorisent que certains des champs d'application.

Déterminer si votre application utilise plusieurs niveaux d'accès

Inspectez le code de votre application ou l'appel réseau sortant pour déterminer si les demandes d'autorisation Google OAuth 2.0 effectuées par votre application entraîneront l'affichage de l'écran de consentement pour les autorisations précises.

Inspecter le code de votre application

Examinez les sections du code de votre application dans lesquelles vous effectuez des appels aux points de terminaison d'autorisation Google OAuth pour demander l'autorisation aux utilisateurs. Si vous utilisez l'une des bibliothèques clientes des API Google, vous pouvez souvent trouver les niveaux d'accès demandés par votre application dans les étapes d'initialisation du client. Vous trouverez quelques exemples dans la section suivante. Vous devez consulter la documentation des SDK utilisés par votre application pour gérer Google OAuth 2.0 afin de déterminer si votre application est concernée, en utilisant les conseils présentés dans les exemples suivants comme référence.

Google Identity Services

L'extrait de code de la bibliothèque JavaScript Google Identity Services suivant initialise TokenClient avec plusieurs champs d'application non liés à la connexion. L'écran de consentement pour les autorisations détaillées s'affiche lorsque l'application Web demande l'autorisation aux utilisateurs.

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

Python

L'extrait de code suivant utilise le module google-auth-oauthlib.flow pour construire la demande d'autorisation. Le paramètre scope inclut deux scopes de non-connexion. L'écran de consentement pour les autorisations détaillées s'affiche lorsque l'application Web demande l'autorisation aux utilisateurs.

import google.oauth2.credentials
import google_auth_oauthlib.flow

# Use the client_secret.json file to identify the application requesting
# authorization. The client ID (from that file) and access scopes are required.
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
    'client_secret.json',
    scopes=['https://www.googleapis.com/auth/calendar.readonly',
                    'https://www.googleapis.com/auth/contacts.readonly'])

Node.js

L'extrait de code suivant crée un objet google.auth.OAuth2, qui définit les paramètres de la requête d'autorisation dont le paramètre scope inclut deux scopes de non-connexion. L'écran de consentement pour les autorisations détaillées s'affiche lorsque l'application Web demande l'autorisation aux utilisateurs.

const {google} = require('googleapis');

/**
  * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI
  * from the client_secret.json file. To get these credentials for your application, visit
  * https://console.cloud.google.com/apis/credentials.
  */
const oauth2Client = new google.auth.OAuth2(
  YOUR_CLIENT_ID,
  YOUR_CLIENT_SECRET,
  YOUR_REDIRECT_URL
);

// Access scopes for read-only Calendar and Contacts.
const scopes = [
  'https://www.googleapis.com/auth/calendar.readonly',
  'https://www.googleapis.com/auth/contacts.readonly']
];

// Generate a url that asks permissions
const authorizationUrl = oauth2Client.generateAuthUrl({
  // 'online' (default) or 'offline' (gets refresh_token)
  access_type: 'offline',
  /** Pass in the scopes array defined above.
    * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
  scope: scopes,
  // Enable incremental authorization. Recommended as best practices.
  include_granted_scopes: true
});

Inspecter un appel réseau sortant

La méthode d'inspection des appels réseau varie en fonction du type de client de votre application.

Lorsque vous inspectez les appels réseau, recherchez les requêtes envoyées aux points de terminaison d'autorisation Google OAuth et examinez le paramètre scope.

Ces valeurs entraînent l'affichage de l'écran de consentement pour les autorisations précises.

  • Le paramètre scope contient des identifiants d'authentification et des identifiants non liés à l'authentification.

    L'exemple de requête suivant contient les trois champs d'application de connexion et un champ d'application de non-connexion pour afficher les métadonnées des fichiers Google Drive de l'utilisateur :

    https://accounts.google.com/o/oauth2/v2/auth?
    access_type=offline&
    scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile%20openid%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.metadata.readonly&
    include_granted_scopes=true&
    response_type=code&
    redirect_uri=YOUR_REDIRECT_URL&
    client_id=YOUR_CLIENT_ID
  • Le paramètre scope contient plusieurs portées non liées à la connexion.

    L'exemple de requête suivant contient deux champs d'application sans connexion pour afficher les métadonnées Google Drive de l'utilisateur et gérer des fichiers Google Drive spécifiques :

  • https://accounts.google.com/o/oauth2/v2/auth?
    access_type=offline&
    scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.metadata.readonly%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.file&
    include_granted_scopes=true&
    response_type=code&
    redirect_uri=YOUR_REDIRECT_URL&
    client_id=YOUR_CLIENT_ID

Bonnes pratiques pour gérer les autorisations précises

Si vous déterminez que votre application doit être mise à jour pour gérer les autorisations précises, vous devez apporter les modifications nécessaires à votre code pour gérer correctement le consentement pour plusieurs niveaux d'accès. Toutes les applications doivent respecter les bonnes pratiques suivantes :

  1. Consultez le Règlement sur les données utilisateur dans les services d'API Google et assurez-vous de le respecter.
  2. Demandez les niveaux d'accès spécifiques nécessaires à une tâche. Vous devez respecter le règlement Google OAuth 2.0 et ne demander que les habilitations dont vous avez besoin. Vous devez éviter de demander plusieurs niveaux d'accès lors de la connexion, sauf si cela est essentiel pour la fonctionnalité de base de votre application. Regrouper plusieurs niveaux d'accès, en particulier pour les nouveaux utilisateurs qui ne connaissent pas les fonctionnalités de votre application, peut les empêcher de comprendre la nécessité de ces autorisations. Cela peut alerter les utilisateurs et les dissuader d'interagir davantage avec votre application.
  3. Fournissez une justification aux utilisateurs avant de leur demander une autorisation. Expliquez clairement pourquoi votre application a besoin de l'autorisation demandée, ce que vous ferez avec les données de l'utilisateur et comment l'utilisateur bénéficiera de l'approbation de la demande. Nos recherches indiquent que ces explications augmentent la confiance et l'engagement des utilisateurs.
  4. Utilisez l'autorisation incrémentielle chaque fois que votre application demande des champs d'application pour éviter d'avoir à gérer plusieurs jetons d'accès.
  5. Vérifiez les habilitations accordées par les utilisateurs. Lorsque vous demandez plusieurs niveaux d'accès à la fois, les utilisateurs peuvent ne pas accorder tous ceux demandés par votre application. Votre application doit toujours vérifier les habilitations accordées par l'utilisateur et gérer tout refus d'habilitation en désactivant les fonctionnalités concernées. Suivez les règles Google OAuth 2.0 sur la gestion du consentement pour plusieurs périmètres et ne demandez à l'utilisateur de donner son consentement qu'une fois qu'il a clairement indiqué son intention d'utiliser la fonctionnalité spécifique qui nécessite le périmètre.

Mettre à jour votre application pour gérer les autorisations précises

Applications Android

Vous devez consulter la documentation des SDK que vous utilisez pour interagir avec Google OAuth 2.0 et mettre à jour votre application afin de gérer les autorisations précises en fonction des bonnes pratiques.

Si vous utilisez le SDK auth.api.signin des services Play pour interagir avec Google OAuth 2.0, vous pouvez utiliser la fonction requestPermissions pour demander l'ensemble d'habilitations le plus petit possible et la fonction hasPermissions pour vérifier les habilitations accordées par l'utilisateur lors de la demande d'autorisations précises.

Applications d'extensions Chrome

Vous devez utiliser l'API Chrome Identity pour travailler avec Google OAuth 2.0 en suivant les bonnes pratiques.

L'exemple suivant montre comment gérer correctement les autorisations précises.

manifest.json

L'exemple de fichier manifeste déclare deux portées non liées à la connexion pour l'application d'extension Chrome.

{
  "name": "Example Chrome extension application",
  ...
  "permissions": [
      "identity"
    ],
  "oauth2" : {
      "client_id": "YOUR_CLIENT_ID",
      "scopes":["https://www.googleapis.com/auth/calendar.readonly",
                "https://www.googleapis.com/auth/contacts.readonly"]
  }
}

Approche incorrecte

Tout ou rien

Les utilisateurs cliquent sur le bouton pour lancer le processus d'autorisation. L'extrait de code suppose que les utilisateurs sont présentés avec un écran de consentement "tout ou rien" pour les deux portées spécifiées dans le fichier manifest.json. Elle ne vérifie pas les habilitations accordées par les utilisateurs.

oauth.js

...
document.querySelector('button').addEventListener('click', function () {
  chrome.identity.getAuthToken({ interactive: true },
      function (token) {
          if (token === undefined) {
            // User didn't authorize both scopes.
            // Updating the UX and application accordingly
            ...
          } else {
            // User authorized both or one of the scopes.
            // It neglects to check which scopes users granted and assumes users granted all scopes.

            // Calling the APIs, etc.
            ...
          }
      });
});

Approche correcte

Niveaux d'accès les plus petits

Sélectionnez le plus petit ensemble de niveaux d'accès requis.

L'application ne doit demander que l'ensemble minimal de niveaux d'accès nécessaires. Nous vous recommandons de demander un champ d'application à la fois, lorsque votre application en a besoin pour effectuer une tâche.

Dans cet exemple, nous partons du principe que les deux champs d'application déclarés dans le fichier manifest.json constituent l'ensemble minimal de champs d'application requis. Le fichier oauth.js utilise l'API Chrome Identity pour lancer le processus d'autorisation avec Google. Vous devez activer les autorisations précises pour que les utilisateurs puissent contrôler plus précisément les autorisations qu'ils accordent à votre application. Votre application doit gérer correctement la réponse des utilisateurs en vérifiant les habilitations qu'ils autorisent.

oauth.js

...
document.querySelector('button').addEventListener('click', function () {
  chrome.identity.getAuthToken({ interactive: true, enableGranularPermissions: true },
      function (token, grantedScopes) {
          if (token === undefined) {
            // User didn't authorize any scope.
            // Updating the UX and application accordingly
            ...
          } else {
            // User authorized the request. Now, check which scopes were granted.
            if (grantedScopes.includes('https://www.googleapis.com/auth/calendar.readonly'))
            {
              // User authorized Calendar read permission.
              // Calling the APIs, etc.
              ...
            }
            else
            {
              // User didn't authorize Calendar read permission.
              // Update UX and application accordingly
              ...
            }

            if (grantedScopes.includes('https://www.googleapis.com/auth/contacts.readonly'))
            {
              // User authorized Contacts read permission.
              // Calling the APIs, etc.
              ...
            }
            else
            {
              // User didn't authorize Contacts read permission.
              // Update UX and application accordingly
              ...
            }
          }
      });
});

Applications iOS, iPadOS et macOS

Vous devez consulter la documentation des SDK que vous utilisez pour interagir avec Google OAuth 2.0 et mettre à jour votre application afin de gérer les autorisations précises en fonction des bonnes pratiques.

Si vous utilisez la bibliothèque Google Sign-In pour iOS et macOS pour interagir avec Google OAuth 2.0, vous devez consulter la documentation sur la gestion des autorisations précises.

Applications Web

Vous devez consulter la documentation des SDK que vous utilisez pour interagir avec Google OAuth 2.0 et mettre à jour votre application afin de gérer les autorisations précises en fonction des bonnes pratiques.

Accès côté serveur (hors connexion)

Le mode d'accès côté serveur (hors connexion) vous oblige à effectuer les opérations suivantes :
  • Configurez un serveur et définissez un point de terminaison accessible au public pour recevoir le code d'autorisation.
  • Configurez l' URI de redirection de votre point de terminaison public dans Clients page de la console Google Cloud.

L'extrait de code suivant montre un exemple NodeJS qui demande deux portées sans connexion. Les utilisateurs verront l'écran de consentement pour les autorisations précises.

Approche incorrecte

Tout ou rien

Les utilisateurs sont redirigés vers l'URL d'autorisation. L'extrait de code suppose que les utilisateurs sont présentés avec un écran de consentement "tout ou rien" pour les deux portées spécifiées dans le tableau scopes. Elle ne vérifie pas les habilitations accordées par les utilisateurs.

main.js

...
const oauth2Client = new google.auth.OAuth2(
  YOUR_CLIENT_ID,
  YOUR_CLIENT_SECRET,
  YOUR_REDIRECT_URL
);

// Access scopes for two non-Sign-In scopes - Google Calendar and Contacts
const scopes = [
  'https://www.googleapis.com/auth/contacts.readonly',
  'https://www.googleapis.com/auth/calendar.readonly'
];

// Generate a url that asks permissions for the Google Calendar and Contacts scopes
const authorizationUrl = oauth2Client.generateAuthUrl({
  // 'online' (default) or 'offline' (gets refresh_token)
  access_type: 'offline',
  // Pass in the scopes array defined above
  scope: scopes,
  // Enable incremental authorization. Recommended as best practices.
  include_granted_scopes: true
});

async function main() {
  const server = http.createServer(async function (req, res) {
    // Example on redirecting user to Google OAuth 2.0 server.
    if (req.url == '/') {
      res.writeHead(301, { "Location": authorizationUrl });
    }
    // Receive the callback from Google OAuth 2.0 server.
    if (req.url.startsWith('/oauth2callback')) {
      // Handle the Google OAuth 2.0 server response
      let q = url.parse(req.url, true).query;

      if (q.error) {
        // User didn't authorize both scopes.
        // Updating the UX and application accordingly
        ...
      } else {
        // User authorized both or one of the scopes.
        // It neglects to check which scopes users granted and assumes users granted all scopes.

        // Get access and refresh tokens (if access_type is offline)
        let { tokens } = await oauth2Client.getToken(q.code);
        // Calling the APIs, etc.
        ...
      }
    }
    res.end();
  }).listen(80);
}
Approche correcte

Champ d'application le plus petit

Sélectionnez le plus petit ensemble de niveaux d'accès requis.

L'application ne doit demander que l'ensemble minimal de niveaux d'accès nécessaires. Nous vous recommandons de demander un champ d'application à la fois, lorsque votre application en a besoin pour effectuer une tâche. Chaque fois que votre application demande des autorisations, elle doit utiliser l'autorisation incrémentielle pour éviter d'avoir à gérer plusieurs jetons d'accès.

Si votre application doit demander plusieurs champs d'application non liés à la connexion, vous devez toujours utiliser l'autorisation incrémentielle lorsque vous effectuez la demande et vérifier les champs d'application accordés par les utilisateurs.

Dans cet exemple, nous partons du principe que les deux niveaux d'accès indiqués sont nécessaires au bon fonctionnement de l'application. Vous devez activer les autorisations précises pour que les utilisateurs puissent contrôler plus précisément les autorisations qu'ils accordent à votre application. Votre application doit gérer correctement la réponse des utilisateurs en vérifiant les habilitations qu'ils ont accordées.

main.js

...
const oauth2Client = new google.auth.OAuth2(
  YOUR_CLIENT_ID,
  YOUR_CLIENT_SECRET,
  YOUR_REDIRECT_URL
);

// Access scopes for two non-Sign-In scopes - Google Calendar and Contacts
const scopes = [
  'https://www.googleapis.com/auth/contacts.readonly',
  'https://www.googleapis.com/auth/calendar.readonly'
];

// Generate a url that asks permissions for the Google Calendar and Contacts scopes
const authorizationUrl = oauth2Client.generateAuthUrl({
  // 'online' (default) or 'offline' (gets refresh_token)
  access_type: 'offline',
  // Pass in the scopes array defined above
  scope: scopes,
  // Enable incremental authorization. Recommended as best practices.
  include_granted_scopes: true,
  // Set to true to enable more granular permissions for Google OAuth 2.0 client IDs created before 2019.
  // No effect for newer Google OAuth 2.0 client IDs, since more granular permissions is always enabled for them.
  enable_granular_consent: true
});

async function main() {
  const server = http.createServer(async function (req, res) {
    // Redirect users to Google OAuth 2.0 server.
    if (req.url == '/') {
      res.writeHead(301, { "Location": authorizationUrl });
    }
    // Receive the callback from Google OAuth 2.0 server.
    if (req.url.startsWith('/oauth2callback')) {
      // Handle the Google OAuth 2.0 server response
      let q = url.parse(req.url, true).query;

      if (q.error) {
        // User didn't authorize both scopes.
        // Updating the UX and application accordingly
        ...
      } else {
        // Get access and refresh tokens (if access_type is offline)
        let { tokens } = await oauth2Client.getToken(q.code);
        oauth2Client.setCredentials(tokens);

        // User authorized the request. Now, check which scopes were granted.
        if (tokens.scope.includes('https://www.googleapis.com/auth/calendar.readonly'))
        {
          // User authorized Calendar read permission.
          // Calling the APIs, etc.
          ...
        }
        else
        {
          // User didn't authorize Calendar read permission.
          // Calling the APIs, etc.
          ...
        }

        // Check which scopes user granted the permission to application
        if (tokens.scope.includes('https://www.googleapis.com/auth/contacts.readonly'))
        {
          // User authorized Contacts read permission.
          // Calling the APIs, etc.
          ...
        }
        else
        {
          // User didn't authorize Contacts read permission.
          // Update UX and application accordingly
          ...
        }
      }
    }
    res.end();
  }).listen(80);
}

Consultez le guide sur les applications Web côté serveur pour savoir comment accéder aux API Google à partir d'applications basées sur un serveur.

Accès côté client uniquement

  • Pour les applications qui utilisent la bibliothèque JavaScript Google Identity Services pour interagir avec Google OAuth 2.0, consultez cette documentation sur la gestion des autorisations précises.
  • Si votre application effectue directement des appels à l'aide de JavaScript vers les points de terminaison d'autorisation Google OAuth 2.0, consultez cette documentation sur la gestion des autorisations précises.

Tester la gestion des autorisations précises dans votre application mise à jour

  1. Décrivez tous les cas dans lesquels les utilisateurs peuvent répondre aux demandes d'autorisation et le comportement attendu de votre application. Par exemple, si l'utilisateur n'autorise que deux des trois scopes demandés, votre application doit se comporter en conséquence.
  2. Testez votre application avec l'autorisation précise activée. Il existe deux façons d'activer les autorisations précises :
    1. Vérifiez les écrans de consentement OAuth 2.0 de votre application pour voir si les autorisations précises sont déjà activées pour votre application. Vous pouvez également créer un ID client Google OAuth 2.0 Web, Android ou iOS dans la console Google Cloud à des fins de test, car l'autorisation précise est toujours activée pour ces ID.
    2. Définissez le paramètre enable_granular_consent sur true lorsque vous appelez les points de terminaison d'autorisation Google OAuth. Certains SDK sont explicitement compatibles avec ce paramètre. Pour les autres, consultez la documentation pour savoir comment ajouter manuellement ce paramètre et sa valeur. Si votre implémentation ne permet pas d'ajouter le paramètre, vous pouvez créer un ID client Google OAuth 2.0 Web, Android ou iOS dans la console Google Cloud à des fins de test uniquement, comme indiqué dans le point précédent.
  3. Lorsque vous testez votre application mise à jour, utilisez un compte Google personnel (@gmail.com) au lieu d'un compte Workspace. En effet, les applications Workspace Enterprise avec délégation d'autorité à l'échelle du domaine ou marquées comme fiables ne sont pas affectées par les modifications apportées aux autorisations précises pour le moment. Par conséquent, il est possible que les tests effectués avec un compte Workspace de votre organisation n'affichent pas le nouvel écran d'autorisation détaillée comme prévu.