Come gestire le autorizzazioni granulari

Panoramica

Con autorizzazioni granulari, i consumatori hanno un controllo più granulare sui dati dell'account che scelgono di condividere con ciascuna app. Vantaggio sia per gli utenti che per gli sviluppatori offrendo controllo, trasparenza e sicurezza maggiori. Questa guida ti aiuterà a comprendere le modifiche necessarie e i passaggi per aggiornare correttamente le tue applicazioni in modo da gestire le autorizzazioni granulari.

Che cos'è l'autorizzazione granulare?

Immagina di sviluppare un'app di produttività che richiede ambiti sia per email che per calendario. Gli utenti potrebbero voler utilizzare la tua applicazione solo per Google Calendar, ma non per Gmail. Grazie alle autorizzazioni OAuth granulari, gli utenti possono scegliere di concedere solo l'autorizzazione per Google Calendar, ma non per Gmail. Consentendo agli utenti di concedere l'accesso a dati specifici, questo riduce al minimo l'esposizione dei dati, rafforza la fiducia e consente agli utenti di avere un controllo sulla loro vita digitale incentrato sulla privacy. È importante progettare l'applicazione per gestire questi scenari.

Quando è richiesto più di un ambito senza accesso

Ambiti di accesso e non di accesso

Per le applicazioni che richiedono ambiti sia di accesso che non di accesso, gli utenti visualizzano prima la pagina di consenso per gli ambiti di accesso (email, profile e openid). Dopo aver acconsentito a condividere le proprie informazioni di base sull'identità (nome, indirizzo email e foto del profilo), gli utenti vedranno una schermata di consenso granulare per gli ambiti non di accesso. In questo caso, l'applicazione deve verificare quali ambiti sono concessi dagli utenti e non può presumere che questi concedano tutti gli ambiti richiesti. Nell'esempio seguente, l'applicazione web richiede tutti e tre gli ambiti di accesso e un ambito senza accesso a Google Drive. Dopo che gli utenti hanno acconsentito agli ambiti di accesso, vedranno la schermata per il consenso delle autorizzazioni granulari per l'autorizzazione Google Drive:

Ambiti di accesso e non di accesso

Più di un ambito senza accesso

Quando le applicazioni richiedono più di un ambito non di accesso, agli utenti verrebbe mostrata una schermata di consenso granulare. Gli utenti possono selezionare le autorizzazioni da approvare per la condivisione con l'applicazione. Di seguito è riportata una schermata per il consenso granulare di esempio che richiede l'accesso ai messaggi di Gmail e ai dati di Google Calendar dell'utente:

Più di un ambito senza accesso

Per le applicazioni che richiedono solo ambiti di accesso (email, profile e openid), la schermata per il consenso delle autorizzazioni #inspect-your-application-codegranular non è applicabile. Gli utenti approvano o rifiutano l'intera richiesta di accesso. In altre parole, se le applicazioni richiedono solo gli ambiti di accesso (uno, due o tutti e tre), la schermata di consenso granulare non è applicabile.

Per le applicazioni che richiedono un solo ambito senza accesso, la schermata per il consenso delle autorizzazioni granulari non è applicabile. In altre parole, gli utenti approvano o rifiutano l'intera richiesta e la schermata per il consenso non contiene alcuna casella di controllo. La tabella seguente riassume i casi in cui viene visualizzata la schermata per il consenso delle autorizzazioni granulari.

Numero di ambiti di accesso Numero di ambiti senza accesso Schermata per il consenso delle autorizzazioni granulari
1-3 0 Non applicabile
1-3 1+ Applicabili
0 1 Non applicabile
0 2+ Applicabili

Determina se le tue applicazioni sono interessate

Esegui una revisione approfondita di tutte le sezioni dell'applicazione in cui vengono utilizzati gli endpoint di autorizzazione Google OAuth 2.0 per le richieste di autorizzazione. Presta attenzione a coloro che richiedono più ambiti poiché attivano schermate di consenso granulari per le autorizzazioni presentate agli utenti. In questi casi, assicurati che il tuo codice sia in grado di gestire i casi in cui gli utenti autorizzano solo alcuni degli ambiti.

Come determinare se la tua applicazione utilizza più ambiti

Controlla il codice dell'app o la chiamata di rete in uscita per determinare se le richieste di autorizzazione OAuth 2.0 di Google effettuate dalla tua app produrranno la visualizzazione della schermata per il consenso delle autorizzazioni granulari.

Ispeziona il codice dell'applicazione

Esamina le sezioni del codice dell'applicazione in cui effettui chiamate agli endpoint di autorizzazione Google OAuth per richiedere l'autorizzazione agli utenti. Se utilizzi una delle librerie client delle API di Google, spesso puoi trovare gli ambiti richiesti dall'applicazione nei passaggi di inizializzazione del client. Alcuni esempi sono riportati nella sezione che segue. Ti consigliamo di consultare la documentazione degli SDK utilizzati dalla tua applicazione per gestire Google OAuth 2.0 per determinare se l'applicazione è interessata, utilizzando come riferimento le indicazioni fornite negli esempi riportati di seguito.

Servizi di identità Google

Il seguente snippet di codice della libreria JavaScript dei Servizi di identità Google inizializza TokenClient con più ambiti non di accesso. La schermata per il consenso granulare viene visualizzata quando l'app web richiede l'autorizzazione agli utenti.

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

Il seguente snippet di codice utilizza il modulo google-auth-oauthlib.flow per creare la richiesta di autorizzazione. Il parametro scope include due ambiti non di accesso. La schermata per il consenso granulare viene visualizzata quando l'applicazione web richiede l'autorizzazione agli utenti.

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

Lo snippet di codice che segue crea un oggetto google.auth.OAuth2, che definisce i parametri nella richiesta di autorizzazione il cui parametro scope include due ambiti non di accesso. La schermata per il consenso granulare viene visualizzata quando l'app web richiede l'autorizzazione agli utenti.

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
});

Ispeziona chiamata di rete in uscita

Il metodo di ispezione delle chiamate di rete varia a seconda del tipo di client dell'applicazione.

Durante l'ispezione delle chiamate di rete, cerca le richieste inviate agli endpoint di autorizzazione OAuth di Google ed esamina il parametro scope.

Questi valori cause la visualizzazione della schermata per il consenso delle autorizzazioni granulari.

  • Il parametro scope contiene ambiti di accesso e non di accesso.

    Una seguente richiesta di esempio contiene tutti e tre gli ambiti di accesso e un ambito non di accesso per visualizzare i metadati dei file di Google Drive dell'utente:

    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
  • Il parametro scope contiene più di un ambito senza accesso.

    Una seguente richiesta di esempio contiene due ambiti non di accesso per visualizzare i metadati di Google Drive dell'utente e gestire file specifici di Google Drive:

  • 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

Best practice per la gestione di autorizzazioni granulari

Se determine che la tua applicazione deve essere aggiornata per gestire le autorizzazioni granulari, devi apportare gli aggiornamenti necessari al codice per gestire correttamente il consenso per più ambiti. Tutte le applicazioni devono rispettare le seguenti best practice:

  1. Esamina le Norme sui dati utente: servizi API di Google e assicurati di rispettarle.
  2. Richiedi gli ambiti specifici necessari per un'attività. Devi rispettare le norme Google OAuth 2.0 che richiedi solo gli ambiti necessari. Evita di chiedere più ambiti al momento dell'accesso, a meno che non siano essenziali per la funzionalità di base della tua app. Raggruppare diversi ambiti, in particolare per i nuovi utenti che non hanno familiarità con le funzionalità della tua applicazione, può rendere difficile comprendere la necessità di queste autorizzazioni. Ciò potrebbe far scattare allarmi e impedire agli utenti di interagire ulteriormente con la tua applicazione.
  3. Fornire una giustificazione agli utenti prima di chiedere la richiesta di autorizzazione. Spiega chiaramente perché la tua applicazione richiede l'autorizzazione richiesta, cosa farai con i dati dell'utente e in che modo l'utente potrà trarre vantaggio dall'approvazione della richiesta. La nostra ricerca indica che queste spiegazioni aumentano la fiducia e il coinvolgimento degli utenti.
  4. Utilizza l'autorizzazione incrementale ogni volta che l'applicazione richiede ambiti per evitare di dover gestire più token di accesso.
  5. Verifica quali ambiti sono stati concessi dagli utenti. Quando richiedi più ambiti contemporaneamente, gli utenti possono non concedere tutti gli ambiti richiesti dalla tua applicazione. L'app deve sempre verificare quali ambiti sono stati concessi dall'utente e gestire eventuali ambiti di negazione disattivando le funzionalità pertinenti. Segui le norme di Google OAuth 2.0 sulla gestione del consenso per più ambiti e chiedi nuovamente all'utente il consenso solo dopo aver indicato chiaramente l'intenzione di utilizzare la funzionalità specifica che richiede l'ambito.

Aggiorna l'applicazione per gestire le autorizzazioni granulari

App per Android

Consulta la documentazione degli SDK che utilizzi per interagire con Google OAuth 2.0 e aggiornare l'applicazione in modo da gestire autorizzazioni granulari in base alle best practice.

Se utilizzi l'SDK auth.api.signin di Play Services per interagire con Google OAuth 2.0, puoi utilizzare la funzione requestPermissions per richiedere l'insieme più ridotto di ambiti necessario e la funzione hasPermissions per verificare gli ambiti concessi all'utente durante la richiesta di autorizzazioni granulari.

Applicazioni di estensioni di Chrome

Devi utilizzare l'API Chrome Identity per utilizzare Google OAuth 2.0 in base alle best practice.

L'esempio seguente mostra come gestire correttamente le autorizzazioni granulari.

manifest.json

Il file manifest di esempio dichiara due ambiti non di accesso per l'applicazione di estensione di 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"]
  }
}

Approccio errato

Tutto o niente

Gli utenti fanno clic sul pulsante per avviare il processo di autorizzazione. Lo snippet di codice presuppone che agli utenti venga mostrata una schermata per il consenso "tutto o niente" per i due ambiti specificati nel file manifest.json. Trascura la verifica degli ambiti concessi dagli utenti.

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.
            ...
          }
      });
});

Approccio corretto

Ambiti più piccoli

Seleziona l'insieme più piccolo di ambiti necessario

L'applicazione deve richiedere solo l'insieme più piccolo di ambiti necessario. È consigliabile che l'applicazione richieda un ambito alla volta quando è necessario per completare un'attività.

In questo esempio, si presume che entrambi gli ambiti dichiarati nel file manifest.json siano l'insieme più piccolo necessario. Il file oauth.js utilizza l'API Chrome Identity per avviare il processo di autorizzazione con Google. Dovresti attivare l'abilitazione di autorizzazioni granulari, in modo che gli utenti abbiano un maggiore controllo sulla concessione delle autorizzazioni alla tua applicazione. L'applicazione deve gestire correttamente la risposta degli utenti controllando gli ambiti autorizzati dagli utenti.

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
              ...
            }
          }
      });
});

Applicazioni per iOS, iPadOS e macOS

Consulta la documentazione degli SDK che utilizzi per interagire con Google OAuth 2.0 e aggiornare l'applicazione in modo da gestire autorizzazioni granulari in base alle best practice.

Se utilizzi la libreria Accedi con Google per iOS e macOS per interagire con Google OAuth 2.0, consulta la documentazione sulla gestione delle autorizzazioni granulari.

Applicazioni web

Consulta la documentazione degli SDK che utilizzi per interagire con Google OAuth 2.0 e aggiornare l'applicazione in modo da gestire autorizzazioni granulari in base alle best practice.

Accesso lato server (offline)

Per utilizzare la modalità di accesso lato server (offline) devi:
  • Crea un server e definisci un endpoint accessibile pubblicamente per ricevere il codice di autorizzazione.
  • Configura l' URI di reindirizzamento dell'endpoint pubblico nella Credentials page della console Google Cloud.

Il seguente snippet di codice mostra un esempio NodeJS che richiede due ambiti non di accesso. Gli utenti vedranno la schermata per il consenso granulare.

Approccio errato

Tutto o niente

Gli utenti vengono reindirizzati all'URL di autorizzazione. Lo snippet di codice presuppone che agli utenti venga visualizzata una schermata per il consenso "tutto o niente" per i due ambiti specificati nell'ARRARIO scopes. Trascura la verifica degli ambiti concessi dagli utenti.

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);
}
Approccio corretto

Ambito più piccolo

Seleziona l'insieme più piccolo di ambiti necessario

L'applicazione deve richiedere solo l'insieme più piccolo di ambiti necessario. È consigliabile che l'applicazione richieda un ambito alla volta quando è necessario per completare un'attività. Ogni volta che l'applicazione richiede gli ambiti, deve utilizzare l'autorizzazione incrementale per evitare di dover gestire più token di accesso.

Se la tua applicazione deve richiedere più ambiti non di accesso, devi sempre utilizzare l'autorizzazione incrementale quando richiedi e verifica gli ambiti concessi dagli utenti.

In questo esempio, si presume che entrambi gli ambiti indicati siano necessari per il corretto funzionamento dell'app. Dovresti attivare l'abilitazione di autorizzazioni granulari, in modo che gli utenti abbiano un maggiore controllo sulla concessione delle autorizzazioni alla tua applicazione. L'applicazione dovrebbe gestire correttamente la risposta degli utenti verificando quali ambiti hanno autorizzato.

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);
}

Consulta la guida alle app web lato server per scoprire come accedere alle API di Google da applicazioni basate su server.

Accesso solo lato client

  • Per le applicazioni che utilizzano la libreria JavaScript dei servizi di identità Google per interagire con Google OAuth 2.0, consulta questa documentazione sulla gestione delle autorizzazioni granulari.
  • Per le applicazioni che effettuano chiamate direttamente tramite JavaScript agli endpoint di autorizzazione Google OAuth 2.0, consulta questa documentazione sulla gestione delle autorizzazioni granulari.

Testa la tua applicazione aggiornata sulla gestione di autorizzazioni granulari

  1. Illustra tutti i casi in cui gli utenti possono rispondere alle richieste di autorizzazione e il comportamento previsto dall'applicazione. Ad esempio, se l'utente autorizza solo due dei tre ambiti richiesti, l'applicazione dovrebbe comportarsi di conseguenza.
  2. Testa la tua applicazione attivando l'autorizzazione granulare. Esistono due modi per abilitare autorizzazioni granulari:
    1. Controlla le schermate di consenso OAuth 2.0 dell'applicazione per verificare se le autorizzazioni granulari sono già abilitate per la tua applicazione. Puoi anche creare un nuovo ID client Google OAuth 2.0 per web, Android o iOS tramite la console Google Cloud a scopo di test, poiché per questi utenti è sempre abilitata l'autorizzazione granulare.
    2. Imposta il parametro enable_granular_consent su true quando chiami gli endpoint di autorizzazione Google OAuth. Alcuni SDK supportano esplicitamente questo parametro. In altri casi, consulta la documentazione per scoprire come aggiungere manualmente questo parametro e il relativo valore. Se la tua implementazione non supporta l'aggiunta del parametro, puoi creare un nuovo ID client OAuth 2.0 di Google per il web, Android o iOS tramite la console Google Cloud solo a scopo di test, come indicato nel punto precedente.