Gérer les autorisations précises

Présentation

Grâce à des autorisations précises, les utilisateurs bénéficient d'un contrôle plus précis sur les données de compte qu'ils choisissent de partager avec chaque application. Ils profitent aussi bien aux utilisateurs qu'aux développeurs en offrant plus de contrôle, de transparence et de sécurité. Ce guide vous aidera à comprendre les modifications nécessaires et les étapes à suivre pour mettre à jour vos applications afin de gérer des autorisations précises.

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

Imaginez que vous développez une application de productivité qui demande à la fois des champs d'application pour les e-mails et les agendas. Vos utilisateurs souhaiteront peut-être utiliser votre application uniquement pour Google Agenda, mais pas pour Gmail. Grâce à des autorisations OAuth précises, les utilisateurs peuvent choisir d'accorder une autorisation uniquement à Google Agenda, mais pas à Gmail. En permettant aux utilisateurs d'accorder l'accès à des données spécifiques, cela réduit leur exposition, renforce la confiance et leur donne les moyens de contrôler leur vie numérique axée sur la confidentialité. Il est important de concevoir votre application pour gérer de tels scénarios.

Lorsque plusieurs champs d'application non liés à la connexion sont demandés

Habilitations de type "Connexion" et "Non-connexion"

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

Habilitations de type "Connexion" et "Non-connexion"

Plusieurs niveaux d'accès non connectés

Un écran de consentement précis s'affiche pour les utilisateurs lorsque les applications demandent plusieurs niveaux d'accès non-Sign-In. Les utilisateurs peuvent sélectionner les autorisations qu'ils souhaitent autoriser à partager avec l'application. Voici un exemple d'écran de consentement précis demandant l'accès aux messages Gmail et aux données Google Agenda de l'utilisateur:

Plusieurs niveaux d'accès non connectés

Pour les applications qui ne demandent que des champs d'application de connexion (email, profile et openid), l'écran d'autorisation #inspect-your-application-codegranular aux autorisations n'est pas applicable. Les utilisateurs approuvent ou refusent l'intégralité de la demande de connexion. En d'autres termes, si les applications ne demandent que des champs d'application de connexion (un, deux ou les trois), l'écran de consentement précis n'est pas applicable.

Pour les applications qui ne demandent qu'un seul champ d'application non-Sign-In, l'écran de consentement précis de l'autorisation n'est pas applicable. En d'autres termes, les utilisateurs approuvent ou refusent l'intégralité de la demande, et il n'y a pas de case à cocher dans l'écran de consentement. Le tableau suivant récapitule quand l'écran de consentement des autorisations précises s'affiche.

Nombre de champs d'application de la fonctionnalité Sign-In Nombre de champs d'application non connectés É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 affectées

Effectuez un examen approfondi de toutes les sections de votre application où les points de terminaison d'autorisation Google OAuth 2.0 sont utilisés pour les demandes d'autorisation. Tenez compte de celles qui demandent plusieurs niveaux d'accès, car elles permettent d'activer les écrans de consentement précis présentés aux utilisateurs. Dans de tels cas, assurez-vous que votre code peut gérer les cas où les utilisateurs n'autorisent que certains des champs d'application.

Déterminer si votre application utilise plusieurs champs d'application

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înent l'affichage de l'écran de consentement pour les autorisations précises.

Inspecter le code de votre application

Examinez les sections de votre code d'application dans lesquelles vous appelez les points de terminaison d'autorisation Google OAuth pour demander l'autorisation des utilisateurs. Si vous utilisez l'une des bibliothèques clientes pour les API Google, vous pouvez souvent trouver les champs d'application demandés par votre application lors des étapes d'initialisation du client. Vous trouverez quelques exemples dans la section suivante. Reportez-vous à la documentation des SDK que votre application utilise pour gérer Google OAuth 2.0 pour déterminer si elle est concernée, en suivant les instructions des exemples suivants à titre de référence.

Google Identity Services

L'extrait de code suivant de la bibliothèque JavaScript Google Identity Services initialise TokenClient avec plusieurs champs d'application autres que Sign-In. L'écran de consentement précis s'affiche lorsque l'application Web demande une 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 requête d'autorisation. Le paramètre scope inclut deux champs d'application autres que "Sign-In". L'écran de consentement précis s'affiche lorsque l'application Web demande une 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 champs d'application autres que Sign-In. L'écran de consentement précis s'affiche lorsque l'application Web demande une 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 l'appel réseau sortant

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

Lors de l'inspection des 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 cause l'affichage de l'écran de consentement précis pour les autorisations.

  • Le paramètre scope contient des habilitations de type "Sign-In" et des habilitations autres que "Sign-In".

    L'exemple de requête suivant contient les trois champs d'application "Sign-In" et un champ d'application non-Sign-In 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 champs d'application autres que "Sign-In".

    L'exemple de requête suivant contient deux niveaux d'accès non connectés permettant d'afficher les métadonnées Google Drive de l'utilisateur et de 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 des autorisations précises

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

  1. Consultez les Règles sur les données utilisateur dans les services d'API Google et assurez-vous de les respecter.
  2. Demandez les niveaux d'accès spécifiques nécessaires pour une tâche. Vous devez respecter la règle Google OAuth 2.0, qui ne demande que les champs d'application dont vous avez besoin. Évitez de demander plusieurs champs d'application lors de la connexion, sauf si cela est essentiel pour la fonctionnalité de base de votre application. Si vous regroupez plusieurs champs d'application, en particulier pour les nouveaux utilisateurs qui ne connaissent pas les fonctionnalités de votre application, il peut être difficile pour eux de comprendre la nécessité de ces autorisations. Cela peut déclencher l'alarme et dissuader les utilisateurs d'interagir davantage avec votre application.
  3. Présentez une justification aux utilisateurs avant de leur demander la demande d'autorisation. Expliquez clairement pourquoi votre application nécessite cette autorisation, ce que vous ferez des données de l'utilisateur et en quoi l'approbation de la demande sera bénéfique pour l'utilisateur. D'après nos recherches, ces explications renforcent la confiance et l'engagement des utilisateurs.
  4. Utilisez une 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 champs d'application accordés par les utilisateurs. Lorsque vous demandez plusieurs champs d'application à la fois, il est possible que les utilisateurs n'accordent pas toutes les portées demandées par votre application. Votre application doit toujours vérifier les champs d'application autorisés par l'utilisateur et gérer les refus de champs d'application en désactivant les fonctionnalités concernées. Respectez les règles Google OAuth 2.0 concernant la gestion du consentement pour plusieurs champs d'application. N'invitez l'utilisateur à donner son consentement qu'une fois qu'il a clairement indiqué l'intention d'utiliser la fonctionnalité spécifique nécessitant ce champ d'application.

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

Applications Android

Nous vous recommandons de consulter la documentation des SDK que vous utilisez pour interagir avec Google OAuth 2.0 et de mettre à jour votre application pour gérer les autorisations précises conformément aux 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 le plus petit ensemble de champs d'application nécessaire et la fonction hasPermissions pour vérifier les champs d'application accordés par l'utilisateur lorsqu'il demande des autorisations précises.

Applications des extensions Chrome

Vous devez utiliser l'API Chrome Identity pour travailler avec Google OAuth 2.0 conformément aux bonnes pratiques.

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

manifest.json

L'exemple de fichier manifeste déclare deux champs d'application autres que "Sign-In" pour l'application de l'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 ce bouton pour lancer le processus d'autorisation. L'extrait de code part du principe que les utilisateurs se voient présenter un écran de consentement "tout ou rien" pour les deux champs d'application spécifiés dans le fichier manifest.json. Il ne vérifie pas les champs d'application accordés 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

Plus petits champs d'application

Sélectionnez le plus petit ensemble de champs d'application requis

L'application ne doit demander que le plus petit ensemble de champs d'application requis. Il est recommandé que votre application ne demande qu'un champ d'application à la fois lorsqu'elle est nécessaire 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 représentent le plus petit ensemble 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 l' activation d'autorisations précises afin que les utilisateurs puissent mieux contrôler l'attribution d'autorisations à votre application. Votre application doit gérer correctement la réponse des utilisateurs en vérifiant les champs d'application autorisés par les utilisateurs.

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

Nous vous recommandons de consulter la documentation des SDK que vous utilisez pour interagir avec Google OAuth 2.0 et de mettre à jour votre application pour gérer les autorisations précises conformément aux bonnes pratiques.

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

Applications Web

Nous vous recommandons de consulter la documentation des SDK que vous utilisez pour interagir avec Google OAuth 2.0 et de mettre à jour votre application pour gérer les autorisations précises conformément aux bonnes pratiques.

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

Pour utiliser le mode d'accès côté serveur (hors connexion), procédez comme suit :
  • Mettez en place un serveur et définissez un point de terminaison accessible publiquement pour recevoir le code d'autorisation.
  • Configurez l' URI de redirection de votre point de terminaison public dans le fichier Credentials page de la console Google Cloud.

L'extrait de code suivant montre un exemple de requête NodeJS demandant deux champs d'application autres que "Sign-In". Les utilisateurs verront l'écran de consentement précis concernant l'autorisation.

Approche incorrecte

Tout ou rien

Les utilisateurs sont redirigés vers l'URL d'autorisation. L'extrait de code part du principe que les utilisateurs disposent d'un écran de consentement "tout ou rien" pour les deux champs d'application spécifiés dans l'arrary scopes. Il ne vérifie pas les champs d'application accordés 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

Plus petit champ d'application

Sélectionnez le plus petit ensemble de champs d'application requis

L'application ne doit demander que le plus petit ensemble de champs d'application requis. Il est recommandé que votre application ne demande qu'un champ d'application à la fois lorsqu'elle est nécessaire pour effectuer une tâche. Chaque fois que votre application demande des champs d'application, elle doit utiliser une autorisation incrémentielle pour éviter d'avoir à gérer plusieurs jetons d'accès.

Si votre application doit demander plusieurs champs d'application autres que "Sign-In", vous devez toujours utiliser l'autorisation incrémentielle lorsque vous demandez et vérifiez les champs d'application accordés par les utilisateurs.

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

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 des applications Web côté serveur pour découvrir 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, nous vous invitons à consulter cette documentation sur la gestion des autorisations précises.
  • Pour les applications qui passent directement des appels à l'aide de JavaScript vers des points de terminaison d'autorisation Google OAuth 2.0, consultez cette documentation sur la gestion des autorisations précises.

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

  1. Décrivez tous les cas dans lesquels les utilisateurs peuvent répondre aux demandes d'autorisation et le comportement attendu à partir de votre application. Par exemple, si l'utilisateur n'autorise que deux des trois champs d'application demandés, votre application doit se comporter en conséquence.
  2. Testez votre application en activant les autorisations précises. Il existe deux façons d'activer des autorisations précises :
    1. Consultez les écrans de consentement OAuth 2.0 de votre application pour voir si des 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 via la console Google Cloud à des fins de test, car l'autorisation granulaire est toujours activée pour ceux-ci.
    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 d'autres, consultez la documentation pour savoir comment ajouter manuellement ce paramètre et sa valeur. Si votre implémentation ne permet pas d'ajouter ce paramètre, vous pouvez créer un ID client Google OAuth 2.0 Web, Android ou iOS via la console Google Cloud à des fins de test uniquement, comme indiqué au point précédent.