Utilizzo del modello di token

La libreria JavaScript google.accounts.oauth2 ti aiuta a richiedere il consenso dell'utente e a ottenere un token di accesso per lavorare con i dati utente. Si basa sul flusso di concessione implicita OAuth 2.0 ed è progettato per consentirti di chiamare direttamente le API Google utilizzando REST e CORS oppure di utilizzare la nostra libreria client API di Google per JavaScript (nota anche come gapi.client) per un accesso semplice e flessibile alle nostre API più complesse.

Prima di accedere ai dati utente protetti da un browser, gli utenti del tuo sito attivano il selettore di account, le procedure di accesso e il consenso basati sul web di Google e, infine, i server OAuth di Google emettono e restituiscono un token di accesso alla tua app web.

Nel modello di autorizzazione basato su token, non è necessario archiviare i token di aggiornamento per utente sul server di backend.

Ti consigliamo di seguire l'approccio descritto qui anziché le tecniche descritte nella precedente guida OAuth 2.0 per applicazioni web lato client.

Configurazione

Trova o crea un ID client seguendo i passaggi descritti nella guida Ottieni il tuo ID client API di Google. Successivamente, aggiungi la libreria client alle pagine sul tuo sito che chiameranno le API di Google. Infine, inizializza il client per i token. In genere, questa operazione viene eseguita all'interno dell'handler onload della libreria client.

Inizializzare un client di token

Chiama initTokenClient() per inizializzare un nuovo client di token con l'ID client della tua app web. Se vuoi, puoi includere un elenco di uno o più scope a cui l'utente deve accedere:

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

Attiva il flusso di token OAuth 2.0

Utilizza il metodo requestAccessToken() per attivare il flusso UX del token e ottenere un token di accesso. Google chiede all'utente di:

  • Scegliere il proprio account.
  • Accedi all'Account Google, se non l'hai ancora fatto.
  • Concedi il consenso per consentire alla tua app web di accedere a ogni ambito richiesto.

Un gesto dell'utente attiva il flusso di token: <button onclick="client.requestAccessToken();">Authorize me</button>

Google restituisce quindi un TokenResponse contenente un token di accesso e un elenco di ambiti a cui l'utente ha concesso l'accesso o un errore al gestore del callback.

Gli utenti possono chiudere la finestra di scelta dell'account o di accesso, nel qual caso la funzione di callback non verrà invocata.

Il design e l'esperienza utente della tua app devono essere implementati solo dopo un'attenta revisione delle norme di OAuth 2.0 di Google. Queste norme riguardano il lavoro con più ambiti, quando e come gestire il consenso degli utenti e altro ancora.

L'autorizzazione incrementale è una metodologia di progettazione di criteri e app utilizzata per richiedere l'accesso alle risorse, utilizzando gli ambiti, solo in base alle esigenze anziché in anticipo e tutte contemporaneamente. Gli utenti possono approvare o rifiutare la condivisione delle singole risorse richieste dalla tua app. Si tratta delle autorizzazioni granulari.

Durante questa procedura, Google richiede il consenso dell'utente, elencando singolarmente ogni ambito richiesto. Gli utenti selezionano le risorse da condividere con la tua app e, infine, Google invoca la tua funzione di callback per restituire un token di accesso e gli ambiti approvati dall'utente. L'app gestisce quindi in modo sicuro i vari risultati possibili con autorizzazioni granulari.

Tuttavia, ci sono delle eccezioni. Le app Google Workspace Enterprise con delega dell'autorità a livello di dominio o le app contrassegnate come Attendibili, accantonano la schermata per il consenso alle autorizzazioni granulari. Per queste app, gli utenti non vedranno la schermata di consenso per le autorizzazioni granulari. L'app riceverà invece tutti gli ambiti richiesti o nessuno.

Per informazioni più dettagliate, vedi Come gestire le autorizzazioni granulari.

Autorizzazione incrementale

Per le app web, i seguenti due scenari di alto livello mostrano l'autorizzazione incrementale utilizzando:

  • Un'app Ajax a pagina singola, che spesso utilizza XMLHttpRequest con accesso dinamico alle risorse.
  • Più pagine web, le risorse sono separate e gestite su base di pagina.

Questi due scenari sono presentati per illustrare considerazioni e metodologie di progettazione, ma non intendono essere consigli completi su come integrare il consenso nella tua app. Le app reali potrebbero utilizzare una variante o una combinazione di queste tecniche.

Ajax

Aggiungi il supporto dell'autorizzazione incrementale alla tua app effettuando più chiamate a requestAccessToken() e utilizzando il parametro scope dell'oggetto OverridableTokenClientConfig per richiedere singoli ambiti al momento del bisogno e solo quando necessario. In questo esempio, le risorse verranno richieste e visibili solo dopo che un gesto dell'utente avrà espanso una sezione di contenuti compressa.

App Ajax
Inizializza il client token al caricamento della pagina:
        const client = google.accounts.oauth2.initTokenClient({
          client_id: 'YOUR_GOOGLE_CLIENT_ID',
          callback: "onTokenResponse",
        });
      
Richiedi il consenso e ottieni i token di accesso tramite i gesti dell'utente. Fai clic su "+" per aprire:

Documenti da leggere

Mostrare i documenti recenti

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

Prossimi eventi

Mostra informazioni sul calendario

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

Visualizzare foto

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

Ogni chiamata a requestAccessToken attiva un momento di consenso dell'utente. La tua app avrà accesso solo alle risorse richieste dalla sezione che un utente sceglie di espandere, limitando così la condivisione delle risorse in base alla scelta dell'utente.

Più pagine web

Quando si progetta per l'autorizzazione incrementale, vengono utilizzate più pagine per richiedere solo gli ambiti richiesti per caricare una pagina, riducendo la complessità e la necessità di effettuare più chiamate per ottenere il consenso dell'utente e recuperare un token di accesso.

App a più pagine
Pagina web Codice
Pagina 1. Documenti da leggere
  const client = google.accounts.oauth2.initTokenClient({
    client_id: 'YOUR_GOOGLE_CLIENT_ID',
    callback: "onTokenResponse",
    scope: 'https://www.googleapis.com/auth/documents.readonly',
  });
  client.requestAccessToken();
          
Pagina 2. Prossimi eventi
  const client = google.accounts.oauth2.initTokenClient({
    client_id: 'YOUR_GOOGLE_CLIENT_ID',
    callback: "onTokenResponse",
    scope: 'https://www.googleapis.com/auth/calendar.readonly',
  });
  client.requestAccessToken();
          
Pagina 3. Carosello di foto
  const client = google.accounts.oauth2.initTokenClient({
    client_id: 'YOUR_GOOGLE_CLIENT_ID',
    callback: "onTokenResponse",
    scope: 'https://www.googleapis.com/auth/photoslibrary.readonly',
  });
  client.requestAccessToken();
          

Ogni pagina richiede l'ambito necessario e ottiene un token di accesso chiamando initTokenClient() e requestAccessToken() al momento del caricamento. In questo scenario, le singole pagine web vengono utilizzate per separare chiaramente le funzionalità e le risorse degli utenti in base all'ambito. In una situazione reale, le singole pagine possono richiedere più ambiti correlati.

Autorizzazioni granulari

Le autorizzazioni granulari vengono gestite allo stesso modo in tutti gli scenari. Dopo che requestAccessToken() ha invocato la funzione di callback e è stato restituito un token di accesso, verifica che l'utente abbia approvato gli ambiti richiesti utilizzando hasGrantedAllScopes() o hasGrantedAnyScope(). Ad esempio:

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

Nella risposta verranno inclusi anche eventuali contributi accettati in precedenza da sessioni o richieste precedenti. Viene mantenuto un record del consenso dell'utente per utente e ID cliente e viene mantenuto in più chiamate a initTokenClient() o requestAccessToken(). Per impostazione predefinita, il consenso dell'utente è necessario solo la prima volta che un utente visita il tuo sito web e richiede un nuovo ambito, ma può essere richiesto a ogni caricamento di pagina utilizzando prompt=consent negli oggetti di configurazione del client token.

Utilizzare i token

Nel modello Token, un token di accesso non viene memorizzato dal sistema operativo o dal browser, ma viene ottenuto inizialmente al momento del caricamento della pagina o successivamente attivando una chiamata a requestAccessToken() tramite un gesto dell'utente, ad esempio la pressione di un pulsante.

Utilizzo di REST e CORS con le API Google

Un token di accesso può essere utilizzato per effettuare richieste autenticate alle API di Google utilizzando REST e CORS. In questo modo, gli utenti possono accedere, concedere il consenso, Google può emettere un token di accesso e il tuo sito può utilizzare i dati dell'utente.

In questo esempio, vengono visualizzati i prossimi eventi nel calendario degli utenti che hanno eseguito l'accesso utilizzando il token di accesso restituito da 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();

Per saperne di più, consulta Come utilizzare CORS per accedere alle API di Google.

La sezione successiva spiega come eseguire facilmente l'integrazione con API più complesse.

Utilizzo della libreria JavaScript delle API di Google

Il client token funziona con la libreria client dell'API di Google per JavaScript. Consulta lo snippet di codice di seguito.

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

Scadenza del token

Per impostazione predefinita, i token di accesso hanno una durata breve. Se il token di accesso scade prima del termine della sessione dell'utente, ottieni un nuovo token chiamando requestAccessToken() da un evento guidato dall'utente, ad esempio la pressione di un pulsante.

Chiama il metodo google.accounts.oauth2.revoke per rimuovere il consenso dell'utente e l'accesso alle risorse per tutti gli ambiti concessi alla tua app. Per revocare questa autorizzazione è necessario un token di accesso valido:

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