OAuth 2.0 per le applicazioni web lato client

Questo documento spiega come implementare l'autorizzazione OAuth 2.0 per accedere alle API di Google da un'applicazione web JavaScript. OAuth 2.0 consente agli utenti di condividere dati specifici con un'applicazione mantenendo privati nomi utente, password e altre informazioni. Ad esempio, un'applicazione può utilizzare OAuth 2.0 per ottenere l'autorizzazione dagli utenti all'archiviazione dei file nei propri Google Drive.

Questo flusso OAuth 2.0 è chiamato implicit grant flow. È progettata per le applicazioni che accedono alle API solo quando l'utente è presente nell'applicazione. Queste applicazioni non possono archiviare informazioni riservate.

In questo flusso, l'app apre un URL Google che utilizza i parametri di ricerca per identificare l'app e il tipo di accesso API richiesto dall'app. Puoi aprire l'URL nella finestra o nel popup del browser corrente. L'utente può eseguire l'autenticazione con Google e concedere le autorizzazioni richieste. Google quindi reindirizza l'utente alla tua app. Il reindirizzamento include un token di accesso, che l'app verifica e che utilizza per effettuare le richieste API.

Prerequisiti

Abilita le API per il tuo progetto

Qualsiasi applicazione che chiami le API di Google deve abilitarle nel API Console.

Per abilitare un'API per il tuo progetto:

  1. Open the API Library in Google API Console.
  2. If prompted, select a project, or create a new one.
  3. L'elenco API Library elenca tutte le API disponibili, raggruppate per famiglia di prodotti e popolarità. Se l'API che vuoi attivare non è visibile nell'elenco, utilizza la funzione di ricerca per trovarla o fai clic su Visualizza tutto nella famiglia di prodotti a cui appartiene.
  4. Seleziona l'API che vuoi attivare, quindi fai clic sul pulsante Abilita.
  5. If prompted, enable billing.
  6. If prompted, read and accept the API's Terms of Service.

Crea credenziali di autorizzazione

Qualsiasi applicazione che utilizzi OAuth 2.0 per accedere alle API di Google deve disporre di credenziali di autorizzazione che identifichino l'applicazione sul server OAuth 2.0 di Google. I passaggi seguenti spiegano come creare le credenziali per il progetto. Le tue applicazioni possono quindi utilizzare le credenziali per accedere alle API che hai abilitato per quel progetto.

  1. Go to the Credentials page.
  2. Fai clic su Crea credenziali > ID client OAuth.
  3. Seleziona il tipo di applicazione Web Application.
  4. Compila il modulo. Le applicazioni che utilizzano JavaScript per effettuare richieste API Google autorizzate devono specificare origini JavaScript autorizzate. Le origini identificano i domini da cui l'applicazione può inviare richieste al server OAuth 2.0. Queste origini devono rispettare le regole di convalida di Google.

Identifica gli ambiti di accesso

Gli ambiti consentono all'applicazione di richiedere l'accesso solo alle risorse necessarie, permettendo al tempo stesso agli utenti di controllare la quantità di accesso da loro concessa. Pertanto, potrebbe esserci una relazione inversa tra il numero di ambiti richiesti e la probabilità di ottenere il consenso dell'utente.

Prima di iniziare a implementare l'autorizzazione OAuth 2.0, ti consigliamo di identificare gli ambiti a cui la tua app dovrà avere l'autorizzazione di accesso.

Il documento Ambiti API OAuth 2.0 contiene un elenco completo di ambiti che potresti utilizzare per accedere alle API di Google.

Ottenere i token di accesso OAuth 2.0

I seguenti passaggi mostrano in che modo la tua applicazione interagisce con il server OAuth 2.0 di Google per ottenere il consenso di un utente a eseguire una richiesta API per conto dell'utente. La tua applicazione deve avere questo consenso prima di poter eseguire una richiesta API di Google che richiede l'autorizzazione dell'utente.

Passaggio 1: configura l'oggetto client

Se utilizzi la libreria client delle API di Google per JavaScript per gestire il flusso OAuth 2.0, il primo passaggio consiste nel configurare gli oggetti gapi.auth2 e gapi.client. Questi oggetti consentono all'applicazione di ottenere l'autorizzazione dell'utente e di effettuare richieste API autorizzate.

L'oggetto client identifica gli ambiti a cui l'applicazione richiede l'accesso. Questi valori informano la schermata di consenso che Google mostra all'utente.

Libreria client JS

La libreria client JavaScript semplifica numerosi aspetti del processo di autorizzazione:

  1. Viene creato l'URL di reindirizzamento per il server di autorizzazione di Google e fornisce un metodo per indirizzare l'utente a tale URL.
  2. Gestisce il reindirizzamento dal server alla tua applicazione.
  3. Convalida il token di accesso restituito dal server di autorizzazione.
  4. Archivia il token di accesso che il server di autorizzazione invia alla tua applicazione e lo recupera quando la tua app effettua chiamate API autorizzate in un secondo momento.

Lo snippet di codice riportato di seguito è un estratto dell'esempio completo mostrato più avanti in questo documento. Questo codice inizializza l'oggetto gapi.client, che la tua applicazione potrebbe utilizzare in seguito per effettuare chiamate API. Una volta creato l'oggetto, viene inizializzato anche l'oggetto gapi.auth2, che viene utilizzato dall'applicazione per controllare e monitorare lo stato di autorizzazione dell'utente.

La chiamata al numero gapi.client.init specifica i seguenti campi:

  • I valori apiKey e clientId specificano le credenziali di autorizzazione dell'applicazione. Come descritto nella sezione relativa alla creazione delle credenziali di autorizzazione, questi valori possono essere ottenuti in API Console. Tieni presente che clientId è obbligatorio se la tua applicazione effettua richieste API autorizzate. Le applicazioni che inviano solo richieste non autorizzate possono semplicemente specificare una chiave API.
  • Il campo scope specifica un elenco di ambiti di accesso delimitati da spazi che corrispondono alle risorse a cui l'applicazione potrebbe accedere per conto dell'utente. Questi valori informano la schermata di consenso che Google mostra all'utente.

    Ti consigliamo di richiedere all'applicazione l'accesso agli ambiti di autorizzazione nel contesto, ove possibile. Richiedendo l'accesso ai dati utente nel contesto, tramite un'autorizzazione incrementale, aiuti gli utenti a comprendere più facilmente il motivo per cui la tua applicazione ha bisogno dell'accesso.

  • Il campo discoveryDocs identifica un elenco di documenti Discovery API utilizzati dalla tua applicazione. Un documento di rilevamento descrive la superficie di un'API, inclusi gli schemi di risorse, e la libreria client JavaScript utilizza tali informazioni per generare metodi che le applicazioni possono utilizzare. In questo esempio, il codice recupera il documento di rilevamento per la versione 3 dell'API Google Drive.

Al termine della chiamata gapi.client.init, il codice imposta la variabile GoogleAuth per identificare l'oggetto Google Auth. Infine, il codice imposta un listener che chiama una funzione quando cambia lo stato di accesso dell'utente. Questa funzione non è definita nello snippet.

var GoogleAuth; // Google Auth object.
function initClient() {
  gapi.client.init({
      'apiKey': 'YOUR_API_KEY',
      'clientId': 'YOUR_CLIENT_ID',
      'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
      'discoveryDocs': ['https://www.googleapis.com/discovery/v1/apis/drive/v3/rest']
  }).then(function () {
      GoogleAuth = gapi.auth2.getAuthInstance();

      // Listen for sign-in state changes.
      GoogleAuth.isSignedIn.listen(updateSigninStatus);
  });
}

Endpoint OAuth 2.0

Se accedi direttamente agli endpoint OAuth 2.0, puoi andare al passaggio successivo.

Passaggio 2: reindirizza al server OAuth 2.0 di Google

Per richiedere l'autorizzazione ad accedere ai dati di un utente, reindirizza l'utente al server OAuth 2.0 di Google.

Libreria client JS

Chiama il metodo GoogleAuth.signIn() per indirizzare l'utente al server di autorizzazione di Google.

GoogleAuth.signIn();

In pratica, l'applicazione potrebbe impostare un valore booleano per determinare se chiamare il metodo signIn() prima di tentare di effettuare una chiamata API.

Lo snippet di codice riportato di seguito mostra come iniziare la procedura di autorizzazione dell'utente. Tieni presenti i seguenti punti relativi allo snippet:

  • L'oggetto GoogleAuth a cui viene fatto riferimento nel codice è uguale alla variabile globale definita nello snippet di codice nel passaggio 1.

  • La funzione updateSigninStatus è un listener che ascolta le modifiche allo stato di autorizzazione dell'utente. Il suo ruolo di listener è stato definito anche nello snippet di codice nel passaggio 1:
    GoogleAuth.isSignedIn.listen(updateSigninStatus);
  • Lo snippet definisce due variabili globali aggiuntive:

    • isAuthorized è una variabile booleana che indica se l'utente ha già eseguito l'accesso. Questo valore può essere impostato quando l'app viene caricata e aggiornata se l'utente accede o esce dall'app.

      In questo snippet, la funzione sendAuthorizedApiRequest controlla il valore della variabile per determinare se l'app deve tentare una richiesta API che richiede autorizzazione o richiedere all'utente di autorizzare l'app.

    • currentApiRequest è un oggetto che memorizza i dettagli relativi all'ultima richiesta API che l'utente ha tentato di eseguire. Il valore dell'oggetto viene impostato quando l'app chiama la funzione sendAuthorizedApiRequest.

      Se l'utente ha autorizzato l'app, la richiesta viene eseguita immediatamente. In caso contrario, la funzione reindirizza l'utente all'accesso. Dopo che l'utente ha eseguito l'accesso, la funzione updateSignInStatus chiama sendAuthorizedApiRequest, trasmettendo la stessa richiesta effettuata prima dell'inizio del flusso di autorizzazione.

var isAuthorized;
var currentApiRequest;

/**
 * Store the request details. Then check to determine whether the user
 * has authorized the application.
 *   - If the user has granted access, make the API request.
 *   - If the user has not granted access, initiate the sign-in flow.
 */
function sendAuthorizedApiRequest(requestDetails) {
  currentApiRequest = requestDetails;
  if (isAuthorized) {
    // Make API request
    // gapi.client.request(requestDetails)

    // Reset currentApiRequest variable.
    currentApiRequest = {};
  } else {
    GoogleAuth.signIn();
  }
}

/**
 * Listener called when user completes auth flow. If the currentApiRequest
 * variable is set, then the user was prompted to authorize the application
 * before the request executed. In that case, proceed with that API request.
 */
function updateSigninStatus(isSignedIn) {
  if (isSignedIn) {
    isAuthorized = true;
    if (currentApiRequest) {
      sendAuthorizedApiRequest(currentApiRequest);
    }
  } else {
    isAuthorized = false;
  }
}

Endpoint OAuth 2.0

Genera un URL per richiedere l'accesso all'endpoint OAuth 2.0 di Google all'indirizzo https://accounts.google.com/o/oauth2/v2/auth. Questo endpoint è accessibile tramite HTTPS; le connessioni HTTP semplici sono rifiutate.

Il server di autorizzazione di Google supporta i seguenti parametri di stringa di query per le applicazioni del server web:

Parametri
client_id Obbligatorio

L'ID client della tua applicazione. Puoi trovare questo valore in API Console Credentials page.

redirect_uri Obbligatorio

Determina dove il server API reindirizza l'utente dopo che quest'ultimo ha completato il flusso di autorizzazione. Il valore deve corrispondere esattamente a uno degli URI di reindirizzamento autorizzati per il client OAuth 2.0, configurato nel API Consoledi Credentials page. Se questo valore non corrisponde a un URI di reindirizzamento autorizzato per l'elemento client_id fornito, verrà visualizzato un errore redirect_uri_mismatch.

Ricorda che lo schema http o https, la distinzione tra maiuscole e minuscole e la barra finale ('/') devono corrispondere.

response_type Obbligatorio

Le applicazioni JavaScript devono impostare il valore del parametro su token. Questo valore indica al server di autorizzazione di Google di restituire il token di accesso come coppia name=value nell'identificatore di frammento dell'URI (#) a cui l'utente viene reindirizzato dopo il completamento del processo di autorizzazione.

scope Obbligatorio

Un elenco di ambiti delimitati da spazi che identificano le risorse a cui la tua applicazione potrebbe accedere per conto dell'utente. Questi valori informano la schermata di consenso che Google mostra all'utente.

Gli ambiti consentono all'applicazione di richiedere l'accesso solo alle risorse necessarie e permette agli utenti di controllare la quantità di accesso da concedere all'applicazione. Pertanto, esiste una relazione inversa tra il numero di ambiti richiesti e la probabilità di ottenere il consenso dell'utente.

Ti consigliamo di richiedere all'applicazione l'accesso agli ambiti di autorizzazione nel contesto ove possibile. Richiedendo l'accesso ai dati utente nel contesto tramite autorizzazione incrementale, aiuti gli utenti a comprendere più facilmente il motivo per cui la tua applicazione ha bisogno dell'accesso.

state Consigliato

Specifica qualsiasi valore stringa utilizzato dall'applicazione per mantenere lo stato tra la richiesta di autorizzazione e la risposta del server di autorizzazione. Il server restituisce il valore esatto che invii come coppia di name=value nell'identificatore di frammento dell'URL (#) di redirect_uri dopo che l'utente ha acconsentito o negato la richiesta di accesso della tua applicazione.

Puoi utilizzare questo parametro per diversi scopi, ad esempio indirizzare l'utente alla risorsa corretta nell'applicazione, inviare nonce e mitigare la falsificazione di richieste tra siti. Poiché redirect_uri può essere indovinato, l'utilizzo di un valore state può aumentare la garanzia che una connessione in entrata sia il risultato di una richiesta di autenticazione. Se generi una stringa casuale o codifica l'hash di un cookie o di un altro valore che acquisisce lo stato del client, puoi convalidare la risposta per assicurarti inoltre che la richiesta e la risposta abbiano origine nello stesso browser, fornendo protezione contro attacchi come la falsificazione di richieste tra siti. Consulta la documentazione OpenID Connect per un esempio di come creare e confermare un token state.

include_granted_scopes Facoltativo

Consente alle applicazioni di utilizzare l'autorizzazione incrementale per richiedere l'accesso ad altri ambiti nel contesto. Se imposti il valore di questo parametro su true e la richiesta di autorizzazione viene concessa, il nuovo token di accesso coprirà anche tutti gli ambiti ai quali l'utente ha concesso l'accesso all'applicazione in precedenza. Consulta la sezione Autorizzazione incrementale per alcuni esempi.

login_hint Facoltativo

Se la tua applicazione sa quale utente sta tentando di eseguire l'autenticazione, può utilizzare questo parametro per fornire un suggerimento al server di autenticazione Google. Il server utilizza il suggerimento per semplificare il flusso di accesso precompilando il campo dell'email nel modulo di accesso o selezionando la sessione multi-accesso appropriata.

Imposta il valore del parametro su un indirizzo email o un identificatore sub, equivalente all'ID Google dell'utente.

prompt Facoltativo

Un elenco di richieste di presentazione dell'utente sensibili alle maiuscole, delimitati da spazi. Se non specifichi questo parametro, all'utente verrà chiesto solo la prima volta che il tuo progetto richiede l'accesso. Per ulteriori informazioni, consulta Richiedere il consenso.

I valori possibili sono:

none Non mostrare schermate di autenticazione o di consenso. Non deve essere specificato con altri valori.
consent Chiedi il consenso all'utente.
select_account Chiedi all'utente di selezionare un account.

Esempio di reindirizzamento al server di autorizzazione di Google

Di seguito viene mostrato un URL di esempio con interruzioni di riga e spazi per una maggiore leggibilità.

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly&
 include_granted_scopes=true&
 response_type=token&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

Dopo aver creato l'URL della richiesta, reindirizzalo all'utente.

Codice di esempio JavaScript

Il seguente snippet JavaScript mostra come avviare il flusso di autorizzazione in JavaScript senza utilizzare la libreria client delle API di Google per JavaScript. Poiché questo endpoint OAuth 2.0 non supporta la condivisione delle risorse tra origini (CORS), lo snippet crea un modulo che apre la richiesta a tale endpoint.

/*
 * Create form to request access token from Google's OAuth 2.0 server.
 */
function oauthSignIn() {
  // Google's OAuth 2.0 endpoint for requesting an access token
  var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';

  // Create <form> element to submit parameters to OAuth 2.0 endpoint.
  var form = document.createElement('form');
  form.setAttribute('method', 'GET'); // Send as a GET request.
  form.setAttribute('action', oauth2Endpoint);

  // Parameters to pass to OAuth 2.0 endpoint.
  var params = {'client_id': 'YOUR_CLIENT_ID',
                'redirect_uri': 'YOUR_REDIRECT_URI',
                'response_type': 'token',
                'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
                'include_granted_scopes': 'true',
                'state': 'pass-through value'};

  // Add form parameters as hidden input values.
  for (var p in params) {
    var input = document.createElement('input');
    input.setAttribute('type', 'hidden');
    input.setAttribute('name', p);
    input.setAttribute('value', params[p]);
    form.appendChild(input);
  }

  // Add form to page and submit it to open the OAuth 2.0 endpoint.
  document.body.appendChild(form);
  form.submit();
}

Passaggio 3: Google chiede all'utente il consenso

In questo passaggio, l'utente decide se concedere alla tua applicazione l'accesso richiesto. In questa fase, Google mostra una finestra di consenso che mostra il nome della tua applicazione e i servizi API di Google a cui richiede l'accesso con le credenziali di autorizzazione dell'utente e un riepilogo degli ambiti di accesso da concedere. L'utente può quindi acconsentire a concedere l'accesso a uno o più ambiti richiesti dalla tua applicazione o rifiutare la richiesta.

In questa fase non è necessario fare nulla perché attende la risposta dal server OAuth 2.0 di Google per indicare se è stato concesso qualsiasi accesso. Questa risposta è spiegata nel passaggio successivo.

Errori

Le richieste inviate all'endpoint di autorizzazione OAuth 2.0 di Google potrebbero mostrare messaggi di errore rivolti agli utenti anziché nei flussi di autenticazione e autorizzazione previsti. Di seguito sono riportati i codici di errore comuni e le relative soluzioni.

admin_policy_enforced

L'Account Google non è in grado di autorizzare uno o più ambiti richiesti a causa dei criteri del suo amministratore di Google Workspace. Consulta l'articolo del Centro assistenza per gli amministratori di Google Workspace Controllare quali app di terze parti e AMP possono accedere ai dati di Google Workspace per saperne di più su come un amministratore può limitare l'accesso a tutti gli ambiti o ad ambiti sensibili e con restrizioni finché non viene concesso esplicitamente l'accesso al tuo ID client OAuth.

disallowed_useragent

L'endpoint di autorizzazione viene visualizzato all'interno di uno user-agent incorporato che non è consentito dai criteri OAuth 2.0 di Google.

Android

Gli sviluppatori Android potrebbero vedere questo messaggio di errore quando aprono le richieste di autorizzazione in android.webkit.WebView. Gli sviluppatori dovrebbero invece utilizzare librerie Android come Accedi con Google per Android o AppAuth per Android tramite OpenID Foundation.

Gli sviluppatori web potrebbero riscontrare questo errore quando un'app Android apre un link web generale in uno user-agent incorporato e un utente accede all'endpoint di autorizzazione OAuth 2.0 di Google dal tuo sito. Gli sviluppatori dovrebbero consentire l'apertura dei link generali nel gestore di link predefinito del sistema operativo, che include sia i gestori di link per app Android sia l'app predefinita del browser. Anche la libreria Schede personalizzate di Android è un'opzione supportata.

iOS

Gli sviluppatori di iOS e macOS potrebbero riscontrare questo errore quando aprono le richieste di autorizzazione in WKWebView. Gli sviluppatori dovrebbero invece utilizzare librerie iOS come Google Accedi per iOS o OpenID Foundation's AppAuth per iOS.

Gli sviluppatori web potrebbero riscontrare questo errore quando un'app per iOS o macOS apre un link web generale in uno user agent incorporato e un utente accede all'endpoint di autorizzazione OAuth 2.0 di Google dal tuo sito. Gli sviluppatori dovrebbero consentire l'apertura dei link generali nel gestore di link predefinito del sistema operativo, che include sia i gestori di link universali sia l'app predefinita del browser. Anche la libreria SFSafariViewController è un'opzione supportata.

org_internal

L'ID client OAuth nella richiesta fa parte di un progetto che limita l'accesso agli Account Google in una specifica organizzazione Google Cloud. Per ulteriori informazioni su questa opzione di configurazione, consulta la sezione Tipo di utente nell'articolo del Centro assistenza dedicato alla configurazione della schermata di consenso OAuth.

origin_mismatch

Lo schema, il dominio e/o la porta del codice JavaScript che ha originato la richiesta di autorizzazione potrebbero non corrispondere a un URI di origine JavaScript autorizzato registrato per l'ID client OAuth. Rivedi le origini JavaScript autorizzate in Google API Console Credentials page.

redirect_uri_mismatch

Il valore redirect_uri inviato nella richiesta di autorizzazione non corrisponde a un URI di reindirizzamento autorizzato per l'ID client OAuth. Rivedi gli URI di reindirizzamento autorizzati nella Google API Console Credentials page.

Lo schema, il dominio e/o la porta del codice JavaScript che ha originato la richiesta di autorizzazione potrebbero non corrispondere a un URI di origine JavaScript autorizzato registrato per l'ID client OAuth. Controlla le origini JavaScript autorizzate in Google API Console Credentials page.

Passaggio 4: gestisci la risposta del server OAuth 2.0

Libreria client JS

La libreria client JavaScript gestisce la risposta dal server di autorizzazione di Google. Se imposti un listener per monitorare le modifiche nello stato di accesso attuale dell'utente, tale funzione viene chiamata quando l'utente concede l'accesso richiesto all'applicazione.

Endpoint OAuth 2.0

Il server OAuth 2.0 invia una risposta al redirect_uri specificato nella richiesta del token di accesso.

Se l'utente approva la richiesta, la risposta contiene un token di accesso. Se l'utente non approva la richiesta, la risposta contiene un messaggio di errore. Il token di accesso o il messaggio di errore viene restituito nel frammento hash dell'URI di reindirizzamento, come mostrato di seguito:

  • Una risposta token di accesso:

    https://oauth2.example.com/callback#access_token=4/P7q7W91&token_type=Bearer&expires_in=3600

    Oltre al parametro access_token, la stringa di frammenti contiene anche il parametro token_type, sempre impostato su Bearer, e il parametro expires_in, che specifica la durata del token, in secondi. Se il parametro state è stato specificato nella richiesta del token di accesso, anche il suo valore è incluso nella risposta.

  • Risposta di errore:
    https://oauth2.example.com/callback#error=access_denied

Esempio di risposta del server OAuth 2.0

Puoi testare questo flusso facendo clic sul seguente URL di esempio, che richiede l'accesso in sola lettura per visualizzare i metadati per i file archiviati sul tuo Google Drive:

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly&
 include_granted_scopes=true&
 response_type=token&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

Una volta completato il flusso OAuth 2.0, la pagina ti reindirizzerà a http://localhost/oauth2callback. L'URL restituirà un errore 404 NOT FOUND a meno che la macchina locale non pubblichi un file a quell'indirizzo. Il passaggio successivo fornisce ulteriori dettagli sulle informazioni restituite nell'URI quando l'utente viene reindirizzato all'applicazione.

Chiamata delle API di Google

Libreria client JS

Dopo che l'applicazione ha ottenuto un token di accesso, puoi utilizzare la libreria client JavaScript per effettuare richieste API per conto dell'utente. La libreria client gestisce il token di accesso per tuo conto e non devi fare nulla di speciale per inviarlo nella richiesta.

La libreria client supporta due metodi per chiamare i metodi API. Se hai caricato un documento di rilevamento, l'API definisce automaticamente le funzioni specifiche del metodo. Puoi anche utilizzare la funzione gapi.client.request per chiamare un metodo API. I due snippet che seguono mostrano queste opzioni per il metodo about.get dell'API Drive.

// Example 1: Use method-specific function
var request = gapi.client.drive.about.get({'fields': 'user'});

// Execute the API request.
request.execute(function(response) {
  console.log(response);
});


// Example 2: Use gapi.client.request(args) function
var request = gapi.client.request({
  'method': 'GET',
  'path': '/drive/v3/about',
  'params': {'fields': 'user'}
});
// Execute the API request.
request.execute(function(response) {
  console.log(response);
});

Endpoint OAuth 2.0

Dopo che l'applicazione ha ottenuto un token di accesso, puoi utilizzarlo per effettuare chiamate a un'API Google per conto di un determinato account utente se sono stati concessi gli ambiti di accesso richiesti dall'API. A tale scopo, includi il token di accesso in una richiesta all'API includendo un parametro di ricerca access_token o un valore Bearer dell'intestazione HTTP Authorization. Se possibile, è preferibile l'intestazione HTTP, perché le stringhe di query tendono a essere visibili nei log del server. Nella maggior parte dei casi puoi utilizzare una libreria client per configurare le chiamate alle API di Google (ad esempio, quando chiami l'API Drive Files).

Puoi provare tutte le API di Google e visualizzarne gli ambiti in OAuth 2.0 Playground.

Esempi GET HTTP

Una chiamata all'endpoint drive.files (l'API Drive File) che utilizza l'intestazione HTTP Authorization: Bearer potrebbe avere il seguente aspetto. Tieni presente che devi specificare il tuo token di accesso:

GET /drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token

Ecco una chiamata alla stessa API per l'utente autenticato utilizzando il parametro della stringa di query access_token:

GET https://www.googleapis.com/drive/v2/files?access_token=access_token

Esempi di curl

Puoi testare questi comandi con l'applicazione a riga di comando curl. Ecco un esempio che utilizza l'opzione di intestazione HTTP (opzione preferita):

curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files

In alternativa, puoi scegliere l'opzione del parametro della stringa di query:

curl https://www.googleapis.com/drive/v2/files?access_token=access_token

Codice di esempio JavaScript

Lo snippet di codice riportato di seguito mostra come utilizzare il sistema CORS (condivisione delle risorse multiorigine) per inviare una richiesta a un'API Google. In questo esempio non viene usata la libreria client delle API di Google per JavaScript. Tuttavia, anche se non utilizzate la libreria client, la guida per l'assistenza CORS nella documentazione della libreria potrebbe aiutarvi a comprendere meglio queste richieste.

In questo snippet di codice, la variabile access_token rappresenta il token che hai ottenuto per effettuare richieste API per conto dell'utente autorizzato. L'esempio completo illustra come archiviare il token nello spazio di archiviazione locale del browser e recuperarlo quando viene effettuata una richiesta API.

var xhr = new XMLHttpRequest();
xhr.open('GET',
    'https://www.googleapis.com/drive/v3/about?fields=user&' +
    'access_token=' + params['access_token']);
xhr.onreadystatechange = function (e) {
  console.log(xhr.response);
};
xhr.send(null);

Completa l'esempio

Libreria client JS

Esempio di demo di codice

Questa sezione contiene una demo funzionante dell'esempio di codice che segue per dimostrare il comportamento del codice in un'app effettiva. Dopo aver autorizzato l'app, questa verrà elencata tra le app collegate al tuo Account Google. L'app è denominata OAuth 2.0 Demo for Google API Docs. Analogamente, se revochi l'accesso e aggiorni la pagina, l'app non sarà più elencata.

Tieni presente che questa app richiede l'accesso all'ambito https://www.googleapis.com/auth/drive.metadata.readonly. L'accesso viene richiesto solo per dimostrare come avviare il flusso OAuth 2.0 in un'applicazione JavaScript. Questa app non effettua richieste API.

Codice di esempio JavaScript

Come mostrato sopra, questo esempio di codice riguarda una pagina (un'app) che carica la libreria client delle API di Google per JavaScript e avvia il flusso OAuth 2.0. La pagina mostra:

  • Un pulsante che consente all'utente di accedere all'applicazione. Se l'utente non ha autorizzato l'app in precedenza, quest'ultima avvia il flusso OAuth 2.0.
  • Due pulsanti che consentono all'utente di uscire dall'app o di revocare l'accesso concesso in precedenza all'app. Se esci da un'app, non hai revocato l'accesso concesso all'app. Dovrai eseguire nuovamente l'accesso prima che l'app possa effettuare altre richieste autorizzate per tuo conto, ma non dovrai concedere di nuovo l'accesso al successivo utilizzo dell'app. Tuttavia, se revochi l'accesso, dovrai concedere di nuovo l'accesso.

Puoi anche revocare l'accesso all'app tramite la pagina Autorizzazioni del tuo Account Google. L'app è elencata come demo di OAuth 2.0 per i documenti dell'API di Google.

<script>
  var GoogleAuth;
  var SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly';
  function handleClientLoad() {
    // Load the API's client and auth2 modules.
    // Call the initClient function after the modules load.
    gapi.load('client:auth2', initClient);
  }

  function initClient() {
    // In practice, your app can retrieve one or more discovery documents.
    var discoveryUrl = 'https://www.googleapis.com/discovery/v1/apis/drive/v3/rest';

    // Initialize the gapi.client object, which app uses to make API requests.
    // Get API key and client ID from API Console.
    // 'scope' field specifies space-delimited list of access scopes.
    gapi.client.init({
        'apiKey': 'YOUR_API_KEY',
        'clientId': 'YOUR_CLIENT_ID',
        'discoveryDocs': [discoveryUrl],
        'scope': SCOPE
    }).then(function () {
      GoogleAuth = gapi.auth2.getAuthInstance();

      // Listen for sign-in state changes.
      GoogleAuth.isSignedIn.listen(updateSigninStatus);

      // Handle initial sign-in state. (Determine if user is already signed in.)
      var user = GoogleAuth.currentUser.get();
      setSigninStatus();

      // Call handleAuthClick function when user clicks on
      //      "Sign In/Authorize" button.
      $('#sign-in-or-out-button').click(function() {
        handleAuthClick();
      });
      $('#revoke-access-button').click(function() {
        revokeAccess();
      });
    });
  }

  function handleAuthClick() {
    if (GoogleAuth.isSignedIn.get()) {
      // User is authorized and has clicked "Sign out" button.
      GoogleAuth.signOut();
    } else {
      // User is not signed in. Start Google auth flow.
      GoogleAuth.signIn();
    }
  }

  function revokeAccess() {
    GoogleAuth.disconnect();
  }

  function setSigninStatus() {
    var user = GoogleAuth.currentUser.get();
    var isAuthorized = user.hasGrantedScopes(SCOPE);
    if (isAuthorized) {
      $('#sign-in-or-out-button').html('Sign out');
      $('#revoke-access-button').css('display', 'inline-block');
      $('#auth-status').html('You are currently signed in and have granted ' +
          'access to this app.');
    } else {
      $('#sign-in-or-out-button').html('Sign In/Authorize');
      $('#revoke-access-button').css('display', 'none');
      $('#auth-status').html('You have not authorized this app or you are ' +
          'signed out.');
    }
  }

  function updateSigninStatus() {
    setSigninStatus();
  }
</script>

<button id="sign-in-or-out-button"
        style="margin-left: 25px">Sign In/Authorize</button>
<button id="revoke-access-button"
        style="display: none; margin-left: 25px">Revoke access</button>

<div id="auth-status" style="display: inline; padding-left: 25px"></div><hr>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script async defer src="https://apis.google.com/js/api.js"
        onload="this.onload=function(){};handleClientLoad()"
        onreadystatechange="if (this.readyState === 'complete') this.onload()">
</script>

Endpoint OAuth 2.0

Questo esempio di codice illustra come completare il flusso OAuth 2.0 in JavaScript senza utilizzare la libreria client delle API di Google per JavaScript. Il codice si riferisce a una pagina HTML che mostra un pulsante per provare una richiesta API. Se fai clic sul pulsante, il codice verifica se la pagina ha archiviato un token di accesso API nello spazio di archiviazione locale del browser. In questo caso, esegue la richiesta API. Altrimenti, avvia il flusso OAuth 2.0.

Per il flusso OAuth 2.0, la pagina segue questi passaggi:

  1. Indirizza l'utente al server OAuth 2.0 di Google, che richiede l'accesso all'ambito https://www.googleapis.com/auth/drive.metadata.readonly.
  2. Dopo aver concesso (o negato) l'accesso a uno o più ambiti richiesti, l'utente viene reindirizzato alla pagina originale, che analizza il token di accesso dalla stringa di identificatore dei frammenti.
  3. La pagina utilizza il token di accesso per effettuare la richiesta API di esempio.

    La richiesta API chiama il metodo about.get dell'API Drive per recuperare le informazioni sull'account Google Drive dell'utente autorizzato.

  4. Se la richiesta viene eseguita correttamente, la risposta API viene registrata nella console di debug del browser.

Puoi revocare l'accesso all'app dalla pagina Autorizzazioni del tuo Account Google. L'app sarà indicata come Demo 2.0 OAuth per i documenti delle API di Google.

Per eseguire questo codice localmente, devi impostare i valori delle variabili YOUR_CLIENT_ID e YOUR_REDIRECT_URI che corrispondono alle credenziali di autorizzazione. La variabile YOUR_REDIRECT_URI deve essere impostata sullo stesso URL in cui viene pubblicata la pagina. Il valore deve corrispondere esattamente a uno degli URI di reindirizzamento autorizzati per il client OAuth 2.0, configurato in API Console Credentials page. Se questo valore non corrisponde a un URI autorizzato, riceverai un errore redirect_uri_mismatch. Il tuo progetto deve inoltre aver attivato l'API appropriata per questa richiesta.

<html><head></head><body>
<script>
  var YOUR_CLIENT_ID = 'REPLACE_THIS_VALUE';
  var YOUR_REDIRECT_URI = 'REPLACE_THIS_VALUE';
  var fragmentString = location.hash.substring(1);

  // Parse query string to see if page request is coming from OAuth 2.0 server.
  var params = {};
  var regex = /([^&=]+)=([^&]*)/g, m;
  while (m = regex.exec(fragmentString)) {
    params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
  }
  if (Object.keys(params).length > 0) {
    localStorage.setItem('oauth2-test-params', JSON.stringify(params) );
    if (params['state'] && params['state'] == 'try_sample_request') {
      trySampleRequest();
    }
  }

  // If there's an access token, try an API request.
  // Otherwise, start OAuth 2.0 flow.
  function trySampleRequest() {
    var params = JSON.parse(localStorage.getItem('oauth2-test-params'));
    if (params && params['access_token']) {
      var xhr = new XMLHttpRequest();
      xhr.open('GET',
          'https://www.googleapis.com/drive/v3/about?fields=user&' +
          'access_token=' + params['access_token']);
      xhr.onreadystatechange = function (e) {
        if (xhr.readyState === 4 && xhr.status === 200) {
          console.log(xhr.response);
        } else if (xhr.readyState === 4 && xhr.status === 401) {
          // Token invalid, so prompt for user permission.
          oauth2SignIn();
        }
      };
      xhr.send(null);
    } else {
      oauth2SignIn();
    }
  }

  /*
   * Create form to request access token from Google's OAuth 2.0 server.
   */
  function oauth2SignIn() {
    // Google's OAuth 2.0 endpoint for requesting an access token
    var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';

    // Create element to open OAuth 2.0 endpoint in new window.
    var form = document.createElement('form');
    form.setAttribute('method', 'GET'); // Send as a GET request.
    form.setAttribute('action', oauth2Endpoint);

    // Parameters to pass to OAuth 2.0 endpoint.
    var params = {'client_id': YOUR_CLIENT_ID,
                  'redirect_uri': YOUR_REDIRECT_URI,
                  'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
                  'state': 'try_sample_request',
                  'include_granted_scopes': 'true',
                  'response_type': 'token'};

    // Add form parameters as hidden input values.
    for (var p in params) {
      var input = document.createElement('input');
      input.setAttribute('type', 'hidden');
      input.setAttribute('name', p);
      input.setAttribute('value', params[p]);
      form.appendChild(input);
    }

    // Add form to page and submit it to open the OAuth 2.0 endpoint.
    document.body.appendChild(form);
    form.submit();
  }
</script>

<button onclick="trySampleRequest();">Try sample request</button>
</body></html>

Regole di convalida dell'origine JavaScript

Google applica le seguenti regole di convalida alle origini JavaScript per aiutare gli sviluppatori a proteggere le loro applicazioni. Le origini JavaScript devono rispettare queste regole. Consulta la sezione 3986 RFC per la definizione di dominio, host e schema, indicata di seguito.

Regole di convalida
Schema

Le origini JavaScript devono utilizzare lo schema HTTPS, non il semplice HTTP. Gli URI localihost (inclusi gli URI degli indirizzi IP Localhost) sono esenti da questa regola.

Organizzatore

Gli host non possono essere indirizzi IP non elaborati. Gli indirizzi IP Localhost sono esentati da questa regola.

Dominio
  • I domini di primo livello host (domini di primo livello) devono appartenere all'elenco dei suffissi pubblici.
  • I domini host non possono essere “googleusercontent.com”.
  • Le origini JavaScript non possono contenere domini di abbreviazione URL (ad esempio goo.gl), a meno che l'app non sia di proprietà del dominio.
  • Informazioni utente

    Le origini JavaScript non possono contenere il componente secondario Userinfo.

    Percorso

    Le origini JavaScript non possono contenere il componente Percorso.

    Query

    Le origini JavaScript non possono contenere il componente della query.

    Frammento

    Le origini JavaScript non possono contenere il componente Frammento.

    Caratteri Le origini JavaScript non possono contenere determinati caratteri, tra cui:
    • Caratteri jolly ('*')
    • Caratteri ASCII non stampabili
    • Codifiche della percentuale non valide (qualsiasi codifica percentuale che non segue la forma di codifica degli URL di un segno percentuale seguita da due cifre esadecimali)
    • Caratteri null (un carattere NULL codificato, ad esempio %00, %C0%80

    Autorizzazione incrementale

    Nel protocollo OAuth 2.0, l'applicazione richiede l'autorizzazione per accedere alle risorse identificate dagli ambiti. Una best practice per l'esperienza utente consiste nel richiedere l'autorizzazione per le risorse nel momento in cui ne hai bisogno. Per abilitare questa pratica, il server di autorizzazione di Google supporta l'autorizzazione incrementale. Questa funzionalità ti consente di richiedere gli ambiti in base alle necessità e, se l'utente concede l'autorizzazione per il nuovo ambito, restituisce un codice di autorizzazione che può essere scambiato con un token contenente tutti gli ambiti concessi dall'utente al progetto.

    Ad esempio, un'app che consente alle persone di campionare le tracce musicali e creare mix potrebbe richiedere pochissime risorse al momento dell'accesso, forse solo il nome della persona che accede. Tuttavia, il salvataggio di un mix completo richiederà l'accesso al suo Google Drive. La maggior parte delle persone lo troverebbe naturale se gli fosse stato richiesto solo l'accesso al proprio Google Drive nel momento in cui l'app ne aveva effettivamente bisogno.

    In questo caso, al momento dell'accesso, l'app potrebbe richiedere gli ambiti openid e profile per eseguire l'accesso di base e, successivamente, richiedere l'ambito https://www.googleapis.com/auth/drive.file al momento della prima richiesta per salvare una combinazione.

    Le seguenti regole si applicano a un token di accesso ottenuto da un'autorizzazione incrementale:

    • Il token può essere utilizzato per accedere a risorse corrispondenti a uno qualsiasi degli ambiti inseriti nella nuova autorizzazione combinata.
    • Quando utilizzi il token di aggiornamento per l'autorizzazione combinata per ottenere un token di accesso, questo token rappresenta l'autorizzazione combinata e può essere utilizzato per qualsiasi valore scope incluso nella risposta.
    • L'autorizzazione combinata include tutti gli ambiti che l'utente ha concesso al progetto API anche se le richieste sono state richieste da client diversi. Ad esempio, se un utente ha concesso l'accesso a un ambito utilizzando un client desktop di un'applicazione e poi ha concesso un altro ambito alla stessa applicazione tramite un client per dispositivi mobili, l'autorizzazione combinata includerà entrambi gli ambiti.
    • Se revochi un token che rappresenta un'autorizzazione combinata, l'accesso a tutti gli ambiti di tale autorizzazione per conto dell'utente associato viene revocato contemporaneamente.

    Gli esempi di codice riportati di seguito mostrano come aggiungere ambiti a un token di accesso esistente. Questo approccio consente alla tua app di evitare di dover gestire più token di accesso.

    Libreria client JS

    Per aggiungere ambiti a un token di accesso esistente, chiama il metodo GoogleUser.grant(options). L'oggetto options identifica gli ambiti aggiuntivi a cui vuoi concedere l'accesso.

    // Space-separated list of additional scope(s) you are requesting access to.
    // This code adds read-only access to the user's calendars via the Calendar API.
    var NEW_SCOPES = 'https://www.googleapis.com/auth/calendar.readonly';
    
    // Retrieve the GoogleUser object for the current user.
    var GoogleUser = GoogleAuth.currentUser.get();
    GoogleUser.grant({'scope': NEW_SCOPES});

    Endpoint OAuth 2.0

    Per aggiungere ambiti a un token di accesso esistente, includi il parametro include_granted_scopes nella richiesta al server OAuth 2.0 di Google.

    Il seguente snippet di codice mostra come fare. Lo snippet presuppone che tu abbia archiviato gli ambiti per cui il token di accesso è valido nello spazio di archiviazione locale del browser. Il codice complete example archivia un elenco di ambiti per i quali il token di accesso è valido impostando la proprietà oauth2-test-params.scope nella memoria locale del browser.

    Lo snippet confronta gli ambiti per cui il token di accesso è valido nell'ambito che vuoi utilizzare per una determinata query. Se il token di accesso non copre questo ambito, viene avviato il flusso OAuth 2.0. Qui, la funzione oauth2SignIn è la stessa che è stata fornita nel passaggio 2 (e fornita più tardi nell'esempio completo).

    var SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly';
    var params = JSON.parse(localStorage.getItem('oauth2-test-params'));
    
    var current_scope_granted = false;
    if (params.hasOwnProperty('scope')) {
      var scopes = params['scope'].split(' ');
      for (var s = 0; s < scopes.length; s++) {
        if (SCOPE == scopes[s]) {
          current_scope_granted = true;
        }
      }
    }
    
    if (!current_scope_granted) {
      oauth2SignIn(); // This function is defined elsewhere in this document.
    } else {
      // Since you already have access, you can proceed with the API request.
    }

    Revoca di un token

    In alcuni casi, un utente potrebbe voler revocare l'accesso concesso a un'applicazione. Un utente può revocare l'accesso visitando le impostazioni dell'account. Per ulteriori informazioni, consulta la sezione Rimuovere il sito o l'accesso alle app del sito di terze parti e delle app con accesso al tuo account.

    È inoltre possibile che un'applicazione revochi in modo programmatico l'accesso concesso. La revoca programmatica è importante nei casi in cui un utente annulla l'iscrizione, rimuove un'applicazione o le risorse API richieste dall'app sono cambiate in modo significativo. In altre parole, una parte del processo di rimozione può includere una richiesta API per garantire la rimozione delle autorizzazioni precedentemente concesse all'applicazione.

    Libreria client JS

    Per revocare in modo programmatico un token, chiama GoogleAuth.disconnect():

    GoogleAuth.disconnect();

    Endpoint OAuth 2.0

    Per revocare un token in modo programmatico, l'applicazione invia una richiesta a https://oauth2.googleapis.com/revoke e include il token come parametro:

    curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \
            https://oauth2.googleapis.com/revoke?token={token}

    Il token può essere un token di accesso o un token di aggiornamento. Se è un token di accesso e ha un token di aggiornamento corrispondente, verrà revocato anche il token di aggiornamento.

    Se la revoca viene elaborata correttamente, il codice di stato HTTP della risposta è 200. Per le condizioni di errore, viene restituito un codice di stato HTTP 400 insieme a un codice di errore.

    Il seguente snippet JavaScript mostra come revocare un token in JavaScript senza utilizzare la libreria client delle API di Google per JavaScript. Poiché l'endpoint OAuth 2.0 di Google per la revoca dei token non supporta la condivisione delle risorse multiorigine (CORS), il codice crea un modulo e invia il modulo all'endpoint anziché utilizzare il metodo XMLHttpRequest() per pubblicare la richiesta.

    function revokeAccess(accessToken) {
      // Google's OAuth 2.0 endpoint for revoking access tokens.
      var revokeTokenEndpoint = 'https://oauth2.googleapis.com/revoke';
    
      // Create <form> element to use to POST data to the OAuth 2.0 endpoint.
      var form = document.createElement('form');
      form.setAttribute('method', 'post');
      form.setAttribute('action', revokeTokenEndpoint);
    
      // Add access token to the form so it is set as value of 'token' parameter.
      // This corresponds to the sample curl request, where the URL is:
      //      https://oauth2.googleapis.com/revoke?token={token}
      var tokenField = document.createElement('input');
      tokenField.setAttribute('type', 'hidden');
      tokenField.setAttribute('name', 'token');
      tokenField.setAttribute('value', accessToken);
      form.appendChild(tokenField);
    
      // Add form to page and submit it to actually revoke the token.
      document.body.appendChild(form);
      form.submit();
    }