Panoramica
Per ottenere un token di accesso per utente per chiamare le API di Google, Google offre più librerie JavaScript:
Questa guida fornisce istruzioni per la migrazione da queste librerie alla libreria dei Servizi di identità Google.
Seguendo questa guida, potrai:
- sostituisci la libreria della piattaforma ritirata con la libreria dei Servizi di identità, e
- Se utilizzi la libreria client API, rimuovi il modulo
gapi.auth2
ritirato, i relativi metodi e oggetti, sostituendoli con gli equivalenti di Identity Services.
Per una descrizione di ciò che è cambiato con la libreria JavaScript di Identity Services, leggi la panoramica e come funziona l'autorizzazione utente per esaminare i termini e i concetti chiave.
Se stai cercando l'autenticazione per la registrazione e l'accesso degli utenti, consulta la pagina Migrazione da Accedi con Google.
Identificare il flusso di autorizzazione
Esistono due possibili flussi di autorizzazione utente: implicito e codice di autorizzazione.
Esamina la tua app web per identificare il tipo di flusso di autorizzazione utilizzato.
Indicazioni che la tua app web utilizza il flusso implicito:
- La tua app web è basata esclusivamente sul browser, senza piattaforma di backend.
- L'utente deve essere presente per chiamare le API di Google, la tua app utilizza solo token di accesso e non richiede token di aggiornamento.
- La tua app web viene caricata
apis.google.com/js/api.js
. - La tua implementazione si basa su OAuth 2.0 per applicazioni web lato client.
- La tua app utilizza i moduli
gapi.client
ogapi.auth2
presenti nella libreria client dell'API di Google per JavaScript.
Indicazioni che la tua app web utilizza il flusso del codice di autorizzazione:
La tua implementazione si basa su:
La tua app viene eseguita sia nel browser dell'utente sia sulla tua piattaforma di backend.
La tua piattaforma di backend ospita un endpoint del codice di autorizzazione.
La tua piattaforma di backend chiama le API di Google per conto degli utenti senza richiedere la loro presenza, anche nota come modalità offline.
I token di aggiornamento vengono gestiti e archiviati dalla piattaforma di backend.
In alcuni casi, il tuo codebase potrebbe supportare entrambi i flussi.
Scegliere un flusso di autorizzazione
Prima di iniziare la migrazione, devi determinare se continuare con il flusso esistente o adottarne uno diverso per soddisfare al meglio le tue esigenze.
Consulta la sezione Scegliere un flusso di autorizzazione per comprendere le principali differenze e i compromessi tra i due flussi.
Nella maggior parte dei casi, è consigliato il flusso del codice di autorizzazione perché offre il massimo livello di sicurezza per gli utenti. L'implementazione di questo flusso consente inoltre alla tua piattaforma di aggiungere nuove funzionalità offline, come il recupero degli aggiornamenti per notificare agli utenti modifiche importanti al calendario, alle foto e agli abbonamenti.
Scegli un flusso di autorizzazione utilizzando i selettori.
Flusso implicito
Ottieni un token di accesso per l'utilizzo nel browser mentre l'utente è presente.
Esempi di flusso implicito mostra le app web prima e dopo la migrazione a Identity Services.
Flusso del codice di autorizzazione
Un codice di autorizzazione per utente emesso da Google viene inviato alla tua piattaforma backend, dove viene poi scambiato con un token di accesso e un token di aggiornamento.
Gli esempi di flusso del codice di autorizzazione mostrano le app web prima e dopo la migrazione a Identity Services.
In questa guida, segui le istruzioni elencate in grassetto per aggiungere, rimuovere, aggiornare o sostituire la funzionalità esistente.
Modifiche all'app web nel browser
Questa sezione esamina le modifiche che apporterai alla tua app web nel browser durante la migrazione alla libreria JavaScript dei servizi di identità Google.
Identificare il codice interessato ed eseguire il test
Un cookie di debug può aiutarti a individuare il codice interessato e a testare il comportamento post-deprecazione.
Nelle app grandi o complesse, potrebbe essere difficile trovare tutto il codice interessato dal ritiro del modulo gapi.auth2
. Per registrare l'utilizzo esistente di funzionalità che verranno
ritirate a breve nella console, imposta il valore del
<x0A>cookie G_AUTH2_MIGRATION
su informational
. Se vuoi, aggiungi i due punti seguiti
da un valore chiave per eseguire anche il logging nell'archiviazione sessione. Dopo l'accesso
e la ricezione della revisione delle credenziali, invia i log raccolti a un backend per l'analisi
successiva. Ad esempio, informational:showauth2use
salva l'origine e l'URL in una chiave di archiviazione della sessione denominata showauth2use
.
Per verificare il comportamento dell'app quando il modulo gapi.auth2
non viene più caricato, imposta il
valore del cookie G_AUTH2_MIGRATION
su enforced
. Ciò consente di testare il comportamento
post-ritiro prima della data di applicazione.
Valori possibili del cookie G_AUTH2_MIGRATION
:
enforced
Non caricare il modulogapi.auth2
.informational
Registra l'utilizzo della funzionalità ritirata nella console JS. Registra anche nell'archiviazione della sessione quando viene impostato un nome chiave facoltativo:informational:key-name
.
Per ridurre al minimo l'impatto sugli utenti, ti consigliamo di impostare questo cookie localmente durante lo sviluppo e il test, prima di utilizzarlo negli ambienti di produzione.
Librerie e moduli
Il modulo gapi.auth2
gestisce l'autenticazione degli utenti per l'accesso e il flusso implicito per l'autorizzazione. Sostituisci questo modulo deprecato, i relativi oggetti e metodi con la libreria dei Servizi di identità Google.
Aggiungi la libreria Identity Services alla tua app web includendola nel tuo documento:
<script src="https://accounts.google.com/gsi/client" async defer></script>
Rimuovi tutte le istanze di caricamento del modulo auth2
utilizzando gapi.load('auth2',
function)
.
La libreria Servizi di identità Google sostituisce l'utilizzo del modulo gapi.auth2
.
Puoi continuare a utilizzare in sicurezza il modulo gapi.client
della libreria client dell'API di Google per JavaScript e sfruttare la creazione automatica di metodi JS chiamabili da un documento di rilevamento, il raggruppamento di più chiamate API e la funzionalità di gestione di CORS.
Cookie
L'autorizzazione utente non richiede l'utilizzo di cookie.
Consulta Migrazione dall'accesso con Google per informazioni dettagliate su come l'autenticazione utente utilizza i cookie e Come Google utilizza i cookie per l'utilizzo dei cookie da parte di altri prodotti e servizi Google.
Credenziali
Google Identity Services separa l'autenticazione e l'autorizzazione degli utenti in due operazioni distinte e le credenziali utente sono separate: il token ID utilizzato per identificare un utente viene restituito separatamente dal token di accesso utilizzato per l'autorizzazione.
Per visualizzare queste modifiche, consulta le credenziali di esempio.
Flusso implicito
Separa l'autenticazione e l'autorizzazione degli utenti rimuovendo la gestione dei profili utente dai flussi di autorizzazione.
Rimuovi questi riferimenti al client JavaScript di Google Sign-In:
Metodi
GoogleUser.getBasicProfile()
GoogleUser.getId()
Flusso del codice di autorizzazione
Identity Services separa le credenziali nel browser in token ID e token di accesso. Questa modifica non si applica alle credenziali ottenute tramite chiamate dirette agli endpoint Google OAuth 2.0 dalla tua piattaforma di backend o tramite librerie in esecuzione su un server sicuro sulla tua piattaforma, ad esempio il client Node.js delle API di Google.
Stato della sessione
In precedenza, Accedi con Google ti aiutava a gestire lo stato di accesso degli utenti utilizzando:
- Gestori di callback per monitorare lo stato della sessione dell'utente.
- Listener per eventi e modifiche allo stato di accesso per l'Account Google di un utente.
Sei responsabile della gestione dello stato di accesso e delle sessioni utente nella tua app web.
Rimuovi questi riferimenti al client JavaScript di Google Sign-In:
Oggetti:
gapi.auth2.SignInOptions
Metodi:
GoogleAuth.attachClickHandler()
GoogleAuth.isSignedIn()
GoogleAuth.isSignedIn.get()
GoogleAuth.isSignedIn.listen()
GoogleAuth.signIn()
GoogleAuth.signOut()
GoogleAuth.currentUser.get()
GoogleAuth.currentUser.listen()
GoogleUser.isSignedIn()
Configurazione client
Aggiorna la tua app web per inizializzare un client token per il flusso di codice di autorizzazione implicito o
Rimuovi questi riferimenti al client JavaScript di Google Sign-In:
Oggetti:
gapi.auth2.ClientConfig
gapi.auth2.OfflineAccessOptions
Metodi:
gapi.auth2.getAuthInstance()
GoogleUser.grant()
Flusso implicito
Aggiungi un oggetto TokenClientConfig
e una chiamata initTokenClient()
per
configurare la tua app web, seguendo l'esempio in inizializzare un client
token.
Sostituisci i riferimenti al client JavaScript di Accedi con Google con i servizi Google Identity:
Oggetti:
gapi.auth2.AuthorizeConfig
conTokenClientConfig
Metodi:
gapi.auth2.init()
congoogle.accounts.oauth2.initTokenClient()
Parametri:
gapi.auth2.AuthorizeConfig.login_hint
conTokenClientConfig.login_hint
.gapi.auth2.GoogleUser.getHostedDomain()
conTokenClientConfig.hd
.
Flusso del codice di autorizzazione
Aggiungi un oggetto CodeClientConfig
e una chiamata initCodeClient()
per configurare
la tua app web, seguendo l'esempio in inizializzare un client di codice.
Quando passi dal flusso implicito al flusso del codice di autorizzazione:
Rimuovi i riferimenti al client JavaScript di Accedi con Google
Oggetti:
gapi.auth2.AuthorizeConfig
Metodi:
gapi.auth2.init()
Parametri:
gapi.auth2.AuthorizeConfig.login_hint
gapi.auth2.GoogleUser.getHostedDomain()
Richiesta di token
Un gesto dell'utente, ad esempio un clic su un pulsante, genera una richiesta che comporta la restituzione di un token di accesso direttamente al browser dell'utente con il flusso implicito oppure alla tua piattaforma di backend dopo lo scambio di un codice di autorizzazione per utente con un token di accesso e un token di aggiornamento.
Flusso implicito
I token di accesso possono essere ottenuti e utilizzati nel browser mentre l'utente ha eseguito l'accesso e ha una sessione attiva con Google. Per la modalità implicita, è necessario un gesto dell'utente per richiedere un token di accesso, anche se è stata effettuata una richiesta precedente.
Sostituisci i riferimenti al client JavaScript di Accedi con Google con i servizi Google Identity:
Metodi:
gapi.auth2.authorize()
conTokenClient.requestAccessToken()
GoogleUser.reloadAuthResponse()
conTokenClient.requestAccessToken()
Aggiungi un link o un pulsante per chiamare requestAccessToken()
per avviare il
flusso UX popup per richiedere un token di accesso o per ottenere un nuovo token quando
quello esistente scade.
Aggiorna il tuo codebase a:
- Attiva il flusso di token OAuth 2.0 con
requestAccessToken()
. - Supporta l'autorizzazione incrementale utilizzando
requestAccessToken
eOverridableTokenClientConfig
per separare una richiesta per molti ambiti in più richieste più piccole. - Richiedi un nuovo token quando quello esistente scade o viene revocato.
L'utilizzo di più ambiti potrebbe richiedere modifiche strutturali al codice sorgente per richiedere l'accesso agli ambiti solo quando sono necessari anziché tutti in una volta, questa operazione è nota come autorizzazione incrementale. Ogni richiesta deve contenere il minor numero possibile di ambiti e, idealmente, un solo ambito. Per ulteriori informazioni su come aggiornare la tua app per l'autorizzazione incrementale, consulta la sezione Come gestire il consenso degli utenti.
Quando un token di accesso scade, il modulo gapi.auth2
ottiene automaticamente
un nuovo token di accesso valido per la tua app web. Per una maggiore sicurezza degli utenti, questo
processo di aggiornamento automatico del token non è supportato dalla libreria Google Identity
Services. La tua app web deve essere aggiornata per rilevare un token di accesso scaduto e richiederne uno nuovo. Per saperne di più, consulta la sezione Gestione dei token.
Flusso del codice di autorizzazione
Aggiungi un link o un pulsante per chiamare requestCode()
e richiedere un codice di autorizzazione
da Google. Per un esempio, consulta Attivare il flusso del codice OAuth 2.0.
Per saperne di più su come rispondere a un token di accesso scaduto o revocato, consulta la sezione Gestione dei token.
Gestione dei token
Aggiungi la gestione degli errori per rilevare le chiamate API di Google non riuscite quando viene utilizzato un token di accesso scaduto o revocato e per richiedere un nuovo token di accesso valido.
Le API di Google restituiscono un codice di stato HTTP 401 Unauthorized
e un messaggio di errore invalid_token
quando viene utilizzato un token di accesso scaduto o revocato. Per un
esempio, consulta Risposta con token non valido.
Token scaduti
I token di accesso hanno una durata breve e spesso sono validi solo per pochi minuti.
Revoca del token
In qualsiasi momento, il proprietario di un Account Google può revocare il consenso precedentemente concesso. In questo modo, i token di accesso e di aggiornamento esistenti vengono invalidati. La revoca può essere
attivata dalla tua piattaforma utilizzando revoke()
o tramite un Account
Google.
Sostituisci i riferimenti al client JavaScript di Accedi con Google con i servizi Google Identity:
Metodi:
getAuthInstance().disconnect()
congoogle.accounts.oauth2.revoke()
GoogleUser.disconnect()
congoogle.accounts.oauth2.revoke()
Chiama revoke
quando un utente elimina il proprio account sulla tua piattaforma o
desidera revocare il consenso alla condivisione dei dati con la tua app.
Prompt per il consenso dell'utente
Google mostra all'utente una finestra di dialogo per il consenso quando la tua app web o la piattaforma backend richiede un token di accesso. Consulta gli esempi di finestre di dialogo per il consenso mostrate da Google agli utenti.
Prima di emettere un token di accesso per la tua app, è necessaria una sessione Google esistente e attiva per richiedere il consenso dell'utente e registrare il risultato. All'utente potrebbe essere richiesto di accedere a un Account Google se non è già stata stabilita una sessione esistente.
Accesso utente
Gli utenti potrebbero aver eseguito l'accesso a un Account Google in una scheda del browser separata o in modo nativo tramite un browser o un sistema operativo. Ti consigliamo di aggiungere Accedi con Google al tuo sito per stabilire una sessione attiva tra un Account Google e il browser quando l'utente apre per la prima volta la tua app. In questo modo, potrai usufruire dei seguenti vantaggi:
- Riduce al minimo il numero di volte in cui un utente deve accedere. La richiesta di un token di accesso avvia la procedura di accesso all'Account Google se non esiste già una sessione attiva.
- Utilizza direttamente il campo credenziale
email
del token ID JWT come valore del parametrologin_hint
negli oggettiCodeClientConfig
oTokenClientConfig
. Ciò è particolarmente utile se la tua piattaforma non gestisce un sistema di gestione degli account utente. - Cerca e associa un Account Google a un account utente locale esistente sulla tua piattaforma, contribuendo a ridurre al minimo gli account duplicati sulla tua piattaforma.
- Quando viene creato un nuovo account locale, le finestre di dialogo e il flusso di registrazione possono essere separati chiaramente dalle finestre di dialogo e dai flussi di autenticazione degli utenti, riducendo il numero di passaggi richiesti e migliorando il tasso di abbandono.
Dopo l'accesso e prima dell'emissione di un token di accesso, gli utenti devono fornire il consenso per la tua applicazione per gli ambiti richiesti.
Risposta del token e del consenso
Dopo il consenso, viene restituito un token di accesso insieme a un elenco di ambiti approvati o rifiutati dall'utente.
Le autorizzazioni granulari consentono agli utenti di approvare o negare singoli ambiti. Quando richiedi l'accesso a più ambiti, ogni ambito viene concesso o rifiutato indipendentemente dagli altri ambiti. In base alla scelta dell'utente, la tua app attiva selettivamente funzionalità che dipendono da un singolo ambito.
Flusso implicito
Sostituisci i riferimenti al client JavaScript di Accedi con Google con i servizi Google Identity:
Oggetti:
gapi.auth2.AuthorizeResponse
conTokenClient.TokenResponse
gapi.auth2.AuthResponse
conTokenClient.TokenResponse
Metodi:
GoogleUser.hasGrantedScopes()
congoogle.accounts.oauth2.hasGrantedAllScopes()
GoogleUser.getGrantedScopes()
congoogle.accounts.oauth2.hasGrantedAllScopes()
Rimuovi i riferimenti al client JavaScript di Accedi con Google:
Metodi:
GoogleUser.getAuthResponse()
Aggiorna la tua app web con hasGrantedAllScopes()
e
hasGrantedAnyScope()
seguendo questo esempio di autorizzazioni granulari.
Flusso del codice di autorizzazione
Aggiorna o aggiungi un endpoint del codice di autorizzazione alla tua piattaforma backend seguendo le istruzioni riportate nella sezione Gestione del codice di autorizzazione.
Aggiorna la tua piattaforma per seguire i passaggi descritti nella guida Utilizzare il modello di codice per convalidare la richiesta e ottenere un token di accesso e un token di aggiornamento.
Aggiorna la tua piattaforma per attivare o disattivare selettivamente funzionalità e funzioni in base agli ambiti individuali approvati dall'utente seguendo le istruzioni per l'autorizzazione incrementale ed esaminando gli ambiti di accesso concessi dall'utente.
Esempi di flusso implicito
Il vecchio modo
Libreria client GAPI
Esempio della libreria client dell'API di Google per JavaScript in esecuzione nel browser utilizzando una finestra di dialogo popup per il consenso dell'utente.
Il modulo gapi.auth2
viene caricato e utilizzato automaticamente da
gapi.client.init()
, pertanto è nascosto.
<!DOCTYPE html>
<html>
<head>
<script src="https://apis.google.com/js/api.js"></script>
<script>
function start() {
gapi.client.init({
'apiKey': 'YOUR_API_KEY',
'clientId': 'YOUR_CLIENT_ID',
'scope': 'https://www.googleapis.com/auth/cloud-translation',
'discoveryDocs': ['https://www.googleapis.com/discovery/v1/apis/translate/v2/rest'],
}).then(function() {
// Execute an API request which is returned as a Promise.
// The method name language.translations.list comes from the API discovery.
return gapi.client.language.translations.list({
q: 'hello world',
source: 'en',
target: 'de',
});
}).then(function(response) {
console.log(response.result.data.translations[0].translatedText);
}, function(reason) {
console.log('Error: ' + reason.result.error.message);
});
};
// Load the JavaScript client library and invoke start afterwards.
gapi.load('client', start);
</script>
</head>
<body>
<div id="results"></div>
</body>
</html>
Libreria client JS
OAuth 2.0 per applicazioni web lato client in esecuzione nel browser utilizzando una finestra di dialogo popup per il consenso dell'utente.
Il modulo gapi.auth2
viene caricato manualmente.
<!DOCTYPE html>
<html><head></head><body>
<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 Google Cloud 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>
</body></html>
Endpoint OAuth 2.0
OAuth 2.0 per applicazioni web lato client in esecuzione nel browser utilizzando i reindirizzamenti a Google per il consenso dell'utente.
Questo esempio mostra le chiamate dirette agli endpoint OAuth 2.0 di Google dal browser dell'utente e non utilizza il modulo gapi.auth2
o una libreria JavaScript.
<!DOCTYPE html>
<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>
Il nuovo modo
Solo GIS
Questo esempio mostra solo la libreria JavaScript di Google Identity Services che utilizza il modello di token e la finestra di dialogo popup per il consenso dell'utente. Viene fornito per illustrare il numero minimo di passaggi necessari per configurare un client, richiedere e ottenere un token di accesso e chiamare un'API di Google.
<!DOCTYPE html>
<html>
<head>
<script src="https://accounts.google.com/gsi/client" onload="initClient()" async defer></script>
</head>
<body>
<script>
var client;
var access_token;
function initClient() {
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: (tokenResponse) => {
access_token = tokenResponse.access_token;
},
});
}
function getToken() {
client.requestAccessToken();
}
function revokeToken() {
google.accounts.oauth2.revoke(access_token, () => {console.log('access token revoked')});
}
function loadCalendar() {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://www.googleapis.com/calendar/v3/calendars/primary/events');
xhr.setRequestHeader('Authorization', 'Bearer ' + access_token);
xhr.send();
}
</script>
<h1>Google Identity Services Authorization Token model</h1>
<button onclick="getToken();">Get access token</button><br><br>
<button onclick="loadCalendar();">Load Calendar</button><br><br>
<button onclick="revokeToken();">Revoke token</button>
</body>
</html>
GAPI async/await
Questo esempio mostra come aggiungere la libreria del servizio di identità Google utilizzando il
modello di token, rimuovere il modulo gapi.auth2
e chiamare un'API utilizzando la
libreria client delle API di Google per JavaScript.
Promesse, async e await vengono utilizzati per applicare l'ordine di caricamento della libreria e per rilevare e riprovare gli errori di autorizzazione. Una chiamata API viene effettuata solo dopo che è disponibile un token di accesso valido.
Gli utenti devono premere il pulsante "Mostra calendario" quando il token di accesso non è presente al primo caricamento della pagina o in un secondo momento, dopo la scadenza del token di accesso.
<!DOCTYPE html>
<html>
<head>
<title>GAPI and GIS Example</title>
<script async defer src="https://apis.google.com/js/api.js" onload="gapiLoad()"></script>
<script async defer src="https://accounts.google.com/gsi/client" onload="gisLoad()"></script>
</head>
<body>
<h1>GAPI Client with GIS Authorization</h1>
<button id="authorizeBtn" style="visibility:hidden;">Authorize and Load Events</button>
<button id="revokeBtn" style="visibility:hidden;">Revoke Access</button>
<div id="content"></div>
<script>
const YOUR_CLIENT_ID = "YOUR_CLIENT_ID";
const YOUR_API_KEY = 'YOUR_API_KEY';
const CALENDAR_SCOPE = 'https://www.googleapis.com/auth/calendar.readonly';
let tokenClient;
let libsLoaded = 0;
function gapiLoad() {
gapi.load('client', initGapiClient);
}
async function initGapiClient() {
try {
await gapi.client.init({ apiKey: YOUR_API_KEY });
await gapi.client.load('https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest');
console.log('GAPI client initialized.');
checkAllLoaded();
} catch (err) {
handleError('GAPI initialization failed:', err);
}
}
function gisLoad() {
try {
tokenClient = google.accounts.oauth2.initTokenClient({
client_id: YOUR_CLIENT_ID,
scope: CALENDAR_SCOPE,
callback: '', // Will be set dynamically
error_callback: handleGisError,
});
console.log('GIS TokenClient initialized.');
checkAllLoaded();
} catch (err) {
handleError('GIS initialization failed:', err);
}
}
function checkAllLoaded() {
libsLoaded++;
if (libsLoaded === 2) {
document.getElementById('authorizeBtn').style.visibility = 'visible';
document.getElementById('revokeBtn').style.visibility = 'visible';
document.getElementById('authorizeBtn').onclick = makeApiCall;
document.getElementById('revokeBtn').onclick = revokeAccess;
console.log('Ready to authorize.');
}
}
function handleGisError(err) {
console.error('GIS Error:', err);
let message = 'An error occurred during authorization.';
if (err && err.type === 'popup_failed_to_open') {
message = 'Failed to open popup. Please disable popup blockers.';
} else if (err && err.type === 'popup_closed') {
message = 'Authorization popup was closed.';
}
document.getElementById('content').textContent = message;
}
function handleError(message, error) {
console.error(message, error);
document.getElementById('content').textContent = `${message} ${error.message || JSON.stringify(error)}`;
}
async function makeApiCall() {
document.getElementById('content').textContent = 'Processing...';
try {
let token = gapi.client.getToken();
if (!token || !token.access_token) {
console.log('No token, fetching one...');
await getToken();
}
console.log('Calling Calendar API...');
const response = await gapi.client.calendar.events.list({ 'calendarId': 'primary' });
displayEvents(response.result);
} catch (err) {
console.error('API call failed:', err);
const errorInfo = err.result && err.result.error;
if (errorInfo && (errorInfo.code === 401 || (errorInfo.code === 403 && errorInfo.status === "PERMISSION_DENIED"))) {
console.log('Auth error on API call, refreshing token...');
try {
await getToken({ prompt: 'consent' }); // Force refresh
const retryResponse = await gapi.client.calendar.events.list({ 'calendarId': 'primary' });
displayEvents(retryResponse.result);
} catch (refreshErr) {
handleError('Failed to refresh token or retry API call:', refreshErr);
}
} else {
handleError('Error loading events:', err.result ? err.result.error : err);
}
}
}
async function getToken(options = { prompt: '' }) {
return new Promise((resolve, reject) => {
if (!tokenClient) return reject(new Error("GIS TokenClient not initialized."));
tokenClient.callback = (tokenResponse) => {
if (tokenResponse.error) {
reject(new Error(`Token Error: ${tokenResponse.error} - ${tokenResponse.error_description}`));
} else {
console.log('Token acquired.');
resolve(tokenResponse);
}
};
tokenClient.requestAccessToken(options);
});
}
function displayEvents(result) {
const events = result.items;
if (events && events.length > 0) {
let eventList = '<h3>Upcoming Events:</h3><ul>' + events.map(event =>
`<li>${event.summary} (${event.start.dateTime || event.start.date})</li>`
).join('') + '</ul>';
document.getElementById('content').innerHTML = eventList;
} else {
document.getElementById('content').textContent = 'No upcoming events found.';
}
}
function revokeAccess() {
const token = gapi.client.getToken();
if (token && token.access_token) {
google.accounts.oauth2.revoke(token.access_token, () => {
console.log('Access revoked.');
document.getElementById('content').textContent = 'Access has been revoked.';
gapi.client.setToken(null);
});
} else {
document.getElementById('content').textContent = 'No token to revoke.';
}
}
</script>
</body>
</html>
Callback GAPI
Questo esempio mostra come aggiungere la libreria del servizio di identità Google utilizzando il
modello di token, rimuovere il modulo gapi.auth2
e chiamare un'API utilizzando la
libreria client delle API di Google per JavaScript.
Le variabili vengono utilizzate per applicare l'ordine di caricamento della libreria. Le chiamate GAPI vengono effettuate dal callback dopo la restituzione di un token di accesso valido.
Gli utenti devono premere il pulsante Mostra calendario al primo caricamento della pagina e di nuovo quando vogliono aggiornare le informazioni del calendario.
<!DOCTYPE html>
<html>
<head>
<script async defer src="https://apis.google.com/js/api.js" onload="gapiLoad()"></script>
<script async defer src="https://accounts.google.com/gsi/client" onload="gisInit()"></script>
</head>
<body>
<h1>GAPI with GIS callbacks</h1>
<button id="showEventsBtn" onclick="showEvents();">Show Calendar</button><br><br>
<button id="revokeBtn" onclick="revokeToken();">Revoke access token</button>
<script>
let tokenClient;
let gapiInited;
let gisInited;
document.getElementById("showEventsBtn").style.visibility="hidden";
document.getElementById("revokeBtn").style.visibility="hidden";
function checkBeforeStart() {
if (gapiInited && gisInited){
// Start only when both gapi and gis are initialized.
document.getElementById("showEventsBtn").style.visibility="visible";
document.getElementById("revokeBtn").style.visibility="visible";
}
}
function gapiInit() {
gapi.client.init({
// NOTE: OAuth2 'scope' and 'client_id' parameters have moved to initTokenClient().
})
.then(function() { // Load the Calendar API discovery document.
gapi.client.load('https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest');
gapiInited = true;
checkBeforeStart();
});
}
function gapiLoad() {
gapi.load('client', gapiInit)
}
function gisInit() {
tokenClient = google.accounts.oauth2.initTokenClient({
client_id: 'YOUR_CLIENT_ID',
scope: 'https://www.googleapis.com/auth/calendar.readonly',
callback: '', // defined at request time
});
gisInited = true;
checkBeforeStart();
}
function showEvents() {
tokenClient.callback = (resp) => {
if (resp.error !== undefined) {
throw(resp);
}
// GIS has automatically updated gapi.client with the newly issued access token.
console.log('gapi.client access token: ' + JSON.stringify(gapi.client.getToken()));
gapi.client.calendar.events.list({ 'calendarId': 'primary' })
.then(calendarAPIResponse => console.log(JSON.stringify(calendarAPIResponse)))
.catch(err => console.log(err));
document.getElementById("showEventsBtn").innerText = "Refresh Calendar";
}
// Conditionally ask users to select the Google Account they'd like to use,
// and explicitly obtain their consent to fetch their Calendar.
// NOTE: To request an access token a user gesture is necessary.
if (gapi.client.getToken() === null) {
// Prompt the user to select a Google Account and asked for consent to share their data
// when establishing a new session.
tokenClient.requestAccessToken({prompt: 'consent'});
} else {
// Skip display of account chooser and consent dialog for an existing session.
tokenClient.requestAccessToken({prompt: ''});
}
}
function revokeToken() {
let cred = gapi.client.getToken();
if (cred !== null) {
google.accounts.oauth2.revoke(cred.access_token, () => {console.log('Revoked: ' + cred.access_token)});
gapi.client.setToken('');
document.getElementById("showEventsBtn").innerText = "Show Calendar";
}
}
</script>
</body>
</html>
Esempi di flusso del codice di autorizzazione
L'esperienza utente popup della libreria del servizio Google Identity può utilizzare un reindirizzamento URL per restituire un codice di autorizzazione direttamente all'endpoint token di backend oppure un gestore di callback JavaScript in esecuzione nel browser dell'utente che funge da proxy per la risposta alla tua piattaforma. In entrambi i casi, la tua piattaforma di backend completerà il flusso OAuth 2.0 per ottenere un token di accesso e di aggiornamento valido.
Il vecchio modo
App web lato server
Accedi con Google per le app lato server in esecuzione sulla piattaforma di backend utilizzando un reindirizzamento a Google per il consenso dell'utente.
<!DOCTYPE html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="https://apis.google.com/js/client:platform.js?onload=start" async defer></script>
<script>
function start() {
gapi.load('auth2', function() {
auth2 = gapi.auth2.init({
client_id: 'YOUR_CLIENT_ID',
api_key: 'YOUR_API_KEY',
discovery_docs: ['https://www.googleapis.com/discovery/v1/apis/translate/v2/rest'],
// Scopes to request in addition to 'profile' and 'email'
scope: 'https://www.googleapis.com/auth/cloud-translation',
});
});
}
function signInCallback(authResult) {
if (authResult['code']) {
console.log("sending AJAX request");
// Send authorization code obtained from Google to backend platform
$.ajax({
type: 'POST',
url: 'YOUR_AUTHORIZATION_CODE_ENDPOINT_URL',
// Always include an X-Requested-With header to protect against CSRF attacks.
headers: {
'X-Requested-With': 'XMLHttpRequest'
},
contentType: 'application/octet-stream; charset=utf-8',
success: function(result) {
console.log(result);
},
processData: false,
data: authResult['code']
});
} else {
console.log('error: failed to obtain authorization code')
}
}
</script>
</head>
<body>
<button id="signinButton">Sign In With Google</button>
<script>
$('#signinButton').click(function() {
// Obtain an authorization code from Google
auth2.grantOfflineAccess().then(signInCallback);
});
</script>
</body>
</html>
HTTP/REST con reindirizzamento
Utilizza OAuth 2.0 per applicazioni server web per inviare il codice di autorizzazione dal browser dell'utente alla tua piattaforma di backend. Consenso dell'utente gestito reindirizzando il browser dell'utente a Google.
/\*
\* 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_AUTHORIZATION_CODE_ENDPOINT_URL',
'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();
}
Il nuovo modo
UX del popup GIS
Questo esempio mostra solo la libreria JavaScript dei Servizi di identità Google che utilizza il modello del codice di autorizzazione una finestra di dialogo popup per il consenso dell'utente e il gestore di callback per ricevere il codice di autorizzazione da Google. Viene fornito per illustrare il numero minimo di passaggi necessari per configurare un client, ottenere il consenso e inviare un codice di autorizzazione alla piattaforma backend.
<!DOCTYPE html>
<html>
<head>
<script src="https://accounts.google.com/gsi/client" onload="initClient()" async defer></script>
</head>
<body>
<script>
var client;
function initClient() {
client = google.accounts.oauth2.initCodeClient({
client_id: 'YOUR_CLIENT_ID',
scope: 'https://www.googleapis.com/auth/calendar.readonly',
ux_mode: 'popup',
callback: (response) => {
var code_receiver_uri = 'YOUR_AUTHORIZATION_CODE_ENDPOINT_URI',
// Send auth code to your backend platform
const xhr = new XMLHttpRequest();
xhr.open('POST', code_receiver_uri, true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.onload = function() {
console.log('Signed in as: ' + xhr.responseText);
};
xhr.send('code=' + response.code);
// After receipt, the code is exchanged for an access token and
// refresh token, and the platform then updates this web app
// running in user's browser with the requested calendar info.
},
});
}
function getAuthCode() {
// Request authorization code and obtain user consent
client.requestCode();
}
</script>
<button onclick="getAuthCode();">Load Your Calendar</button>
</body>
</html>
UX di reindirizzamento GIS
Il modello di codice di autorizzazione supporta le modalità UX popup e reindirizzamento per inviare un codice di autorizzazione per utente all'endpoint ospitato dalla tua piattaforma. La modalità UX di reindirizzamento è mostrata qui:
<!DOCTYPE html>
<html>
<head>
<script src="https://accounts.google.com/gsi/client" onload="initClient()" async defer></script>
</head>
<body>
<script>
var client;
function initClient() {
client = google.accounts.oauth2.initCodeClient({
client_id: 'YOUR_CLIENT_ID',
scope: 'https://www.googleapis.com/auth/calendar.readonly \
https://www.googleapis.com/auth/photoslibrary.readonly',
ux_mode: 'redirect',
redirect_uri: 'YOUR_AUTHORIZATION_CODE_ENDPOINT_URI'
});
}
// Request an access token
function getAuthCode() {
// Request authorization code and obtain user consent
client.requestCode();
}
</script>
<button onclick="getAuthCode();">Load Your Calendar</button>
</body>
</html>
Librerie JavaScript
Servizi di identità Google è una singola libreria JavaScript utilizzata per l'autenticazione e l'autorizzazione degli utenti che consolida e sostituisce le funzionalità e le caratteristiche presenti in più librerie e moduli diversi:
Azioni da intraprendere durante la migrazione a Identity Services:
Libreria JS esistente | Nuova libreria JS | Note |
---|---|---|
apis.google.com/js/api.js |
accounts.google.com/gsi/client |
Aggiungi una nuova libreria e segui il flusso implicito. |
apis.google.com/js/client.js |
accounts.google.com/gsi/client |
Aggiungi una nuova libreria e il flusso del codice di autorizzazione. |
Riferimento rapido per le librerie
Confronto tra oggetti e metodi della libreria client JavaScript di Accedi con Google precedente e della libreria Servizi di identità Google nuova e note con informazioni aggiuntive e azioni da intraprendere durante la migrazione.
Vecchio | Nuovo | Note |
---|---|---|
Oggetto GoogleAuth e metodi associati: | ||
GoogleAuth.attachClickHandler() | Rimuovi | |
GoogleAuth.currentUser.get() | Rimuovi | |
GoogleAuth.currentUser.listen() | Rimuovi | |
GoogleAuth.disconnect() | google.accounts.oauth2.revoke | Sostituisci il vecchio con il nuovo. La revoca può avvenire anche dalla pagina https://myaccount.google.com/permissions |
GoogleAuth.grantOfflineAccess() | Rimuovi, segui il flusso del codice di autorizzazione. | |
GoogleAuth.isSignedIn.get() | Rimuovi | |
GoogleAuth.isSignedIn.listen() | Rimuovi | |
GoogleAuth.signIn() | Rimuovi | |
GoogleAuth.signOut() | Rimuovi | |
GoogleAuth.then() | Rimuovi | |
Oggetto GoogleUser e metodi associati: | ||
GoogleUser.disconnect() | google.accounts.id.revoke | Sostituisci il vecchio con il nuovo. La revoca può avvenire anche dalla pagina https://myaccount.google.com/permissions |
GoogleUser.getAuthResponse() | requestCode() or requestAccessToken() | Sostituisci il vecchio con il nuovo |
GoogleUser.getBasicProfile() | Rimuovi. Utilizza invece il token ID. Per maggiori informazioni, consulta la pagina Migrazione da Accedi con Google. | |
GoogleUser.getGrantedScopes() | hasGrantedAnyScope() | Sostituisci il vecchio con il nuovo |
GoogleUser.getHostedDomain() | Rimuovi | |
GoogleUser.getId() | Rimuovi | |
GoogleUser.grantOfflineAccess() | Rimuovi, segui il flusso del codice di autorizzazione. | |
GoogleUser.grant() | Rimuovi | |
GoogleUser.hasGrantedScopes() | hasGrantedAnyScope() | Sostituisci il vecchio con il nuovo |
GoogleUser.isSignedIn() | Rimuovi | |
GoogleUser.reloadAuthResponse() | requestAccessToken() | Rimuovi il token di accesso precedente e chiama quello nuovo per sostituire quello scaduto o revocato. |
Oggetto gapi.auth2 e metodi associati: | ||
Oggetto gapi.auth2.AuthorizeConfig | TokenClientConfig o CodeClientConfig | Sostituisci il vecchio con il nuovo |
Oggetto gapi.auth2.AuthorizeResponse | Rimuovi | |
Oggetto gapi.auth2.AuthResponse | Rimuovi | |
gapi.auth2.authorize() | requestCode() or requestAccessToken() | Sostituisci il vecchio con il nuovo |
gapi.auth2.ClientConfig() | TokenClientConfig o CodeClientConfig | Sostituisci il vecchio con il nuovo |
gapi.auth2.getAuthInstance() | Rimuovi | |
gapi.auth2.init() | initTokenClient() or initCodeClient() | Sostituisci il vecchio con il nuovo |
Oggetto gapi.auth2.OfflineAccessOptions | Rimuovi | |
Oggetto gapi.auth2.SignInOptions | Rimuovi | |
Oggetto gapi.signin2 e metodi associati: | ||
gapi.signin2.render() | Rimuovi. Il caricamento del DOM HTML dell'elemento g_id_signin o la chiamata JS a google.accounts.id.renderButton attiva l'accesso dell'utente a un Account Google. |
Credenziali di esempio
Credenziali esistenti
La libreria della piattaforma Accedi con Google, la libreria client dell'API di Google per JavaScript o le chiamate dirette agli endpoint OAuth 2.0 di Google restituiscono un token di accesso OAuth 2.0 e un token ID OpenID Connect in un'unica risposta.
Risposta di esempio contenente sia access_token
che id_token
:
{
"token_type": "Bearer",
"access_token": "ya29.A0ARrdaM-SmArZaCIh68qXsZSzyeU-8mxhQERHrP2EXtxpUuZ-3oW8IW7a6D2J6lRnZrRj8S6-ZcIl5XVEqnqxq5fuMeDDH_6MZgQ5dgP7moY-yTiKR5kdPm-LkuPM-mOtUsylWPd1wpRmvw_AGOZ1UUCa6UD5Hg",
"scope": "https://www.googleapis.com/auth/calendar.readonly",
"login_hint": "AJDLj6I2d1RH77cgpe__DdEree1zxHjZJr4Q7yOisoumTZUmo5W2ZmVFHyAomUYzLkrluG-hqt4RnNxrPhArd5y6p8kzO0t8xIfMAe6yhztt6v2E-_Bb4Ec3GLFKikHSXNh5bI-gPrsI",
"expires_in": 3599,
"id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjkzNDFhYmM0MDkyYjZmYzAzOGU0MDNjOTEwMjJkZDNlNDQ1MzliNTYiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwiYXpwIjoiNTM4MzQ0NjUzMjU1LTc1OGM1aDVpc2M0NXZnazI3ZDhoOGRlYWJvdnBnNnRvLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiYXVkIjoiNTM4MzQ0NjUzMjU1LTc1OGM1aDVpc2M0NXZnazI3ZDhoOGRlYWJvdnBnNnRvLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwic3ViIjoiMTE3NzI2NDMxNjUxOTQzNjk4NjAwIiwiaGQiOiJnb29nbGUuY29tIiwiZW1haWwiOiJkYWJyaWFuQGdvb2dsZS5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYXRfaGFzaCI6IkJBSW55TjN2MS1ZejNLQnJUMVo0ckEiLCJuYW1lIjoiQnJpYW4gRGF1Z2hlcnR5IiwicGljdHVyZSI6Imh0dHBzOi8vbGgzLmdvb2dsZXVzZXJjb250ZW50LmNvbS9hLS9BT2gxNEdnenAyTXNGRGZvbVdMX3VDemRYUWNzeVM3ZGtxTE5ybk90S0QzVXNRPXM5Ni1jIiwiZ2l2ZW5fbmFtZSI6IkJyaWFuIiwiZmFtaWx5X25hbWUiOiJEYXVnaGVydHkiLCJsb2NhbGUiOiJlbiIsImlhdCI6MTYzODk5MTYzOCwiZXhwIjoxNjM4OTk1MjM4LCJqdGkiOiI5YmRkZjE1YWFiNzE2ZDhjYmJmNDYwMmM1YWM3YzViN2VhMDQ5OTA5In0.K3EA-3Adw5HA7O8nJVCsX1HmGWxWzYk3P7ViVBb4H4BoT2-HIgxKlx1mi6jSxIUJGEekjw9MC-nL1B9Asgv1vXTMgoGaNna0UoEHYitySI23E5jaMkExkTSLtxI-ih2tJrA2ggfA9Ekj-JFiMc6MuJnwcfBTlsYWRcZOYVw3QpdTZ_VYfhUu-yERAElZCjaAyEXLtVQegRe-ymScra3r9S92TA33ylMb3WDTlfmDpWL0CDdDzby2asXYpl6GQ7SdSj64s49Yw6mdGELZn5WoJqG7Zr2KwIGXJuSxEo-wGbzxNK-mKAiABcFpYP4KHPEUgYyz3n9Vqn2Tfrgp-g65BQ",
"session_state": {
"extraQueryParams": {
"authuser": "0"
}
},
"first_issued_at": 1638991637982,
"expires_at": 1638995236982,
"idpId": "google"
}
Credenziale dei servizi di identità Google
La libreria dei servizi Google Identity restituisce:
un token di accesso se utilizzato per l'autorizzazione:
{ "access_token": "ya29.A0ARrdaM_LWSO-uckLj7IJVNSfnUityT0Xj-UCCrGxFQdxmLiWuAosnAKMVQ2Z0LLqeZdeJii3TgULp6hR_PJxnInBOl8UoUwWoqsrGQ7-swxgy97E8_hnzfhrOWyQBmH6zs0_sUCzwzhEr_FAVqf92sZZHphr0g", "token_type": "Bearer", "expires_in": 3599, "scope": "https://www.googleapis.com/auth/calendar.readonly" }
oppure un token ID se utilizzato per l'autenticazione:
{ "clientId": "538344653255-758c5h5isc45vgk27d8h8deabovpg6to.apps.googleusercontent.com", "credential": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImMxODkyZWI0OWQ3ZWY5YWRmOGIyZTE0YzA1Y2EwZDAzMjcxNGEyMzciLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJuYmYiOjE2MzkxNTcyNjQsImF1ZCI6IjUzODM0NDY1MzI1NS03NThjNWg1aXNjNDV2Z2syN2Q4aDhkZWFib3ZwZzZ0by5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbSIsInN1YiI6IjExNzcyNjQzMTY1MTk0MzY5ODYwMCIsIm5vbmNlIjoiZm9vYmFyIiwiaGQiOiJnb29nbGUuY29tIiwiZW1haWwiOiJkYWJyaWFuQGdvb2dsZS5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYXpwIjoiNTM4MzQ0NjUzMjU1LTc1OGM1aDVpc2M0NXZnazI3ZDhoOGRlYWJvdnBnNnRvLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwibmFtZSI6IkJyaWFuIERhdWdoZXJ0eSIsInBpY3R1cmUiOiJodHRwczovL2xoMy5nb29nbGV1c2VyY29udGVudC5jb20vYS0vQU9oMTRHZ3pwMk1zRkRmb21XTF91Q3pkWFFjc3lTN2RrcUxOcm5PdEtEM1VzUT1zOTYtYyIsImdpdmVuX25hbWUiOiJCcmlhbiIsImZhbWlseV9uYW1lIjoiRGF1Z2hlcnR5IiwiaWF0IjoxNjM5MTU3NTY0LCJleHAiOjE2MzkxNjExNjQsImp0aSI6IjRiOTVkYjAyZjU4NDczMmUxZGJkOTY2NWJiMWYzY2VhYzgyMmI0NjUifQ.Cr-AgMsLFeLurnqyGpw0hSomjOCU4S3cU669Hyi4VsbqnAV11zc_z73o6ahe9Nqc26kPVCNRGSqYrDZPfRyTnV6g1PIgc4Zvl-JBuy6O9HhClAK1HhMwh1FpgeYwXqrng1tifmuotuLQnZAiQJM73Gl-J_6s86Buo_1AIx5YAKCucYDUYYdXBIHLxrbALsA5W6pZCqqkMbqpTWteix-G5Q5T8LNsfqIu_uMBUGceqZWFJALhS9ieaDqoxhIqpx_89QAr1YlGu_UO6R6FYl0wDT-nzjyeF5tonSs3FHN0iNIiR3AMOHZu7KUwZaUdHg4eYkU-sQ01QNY_11keHROCRQ", "select_by": "user" }
Risposta al token non valida
Risposta di esempio di Google quando si tenta di effettuare una richiesta API utilizzando un token di accesso scaduto, revocato o non valido:
Intestazioni delle risposte HTTP
www-authenticate: Bearer realm="https://accounts.google.com/", error="invalid_token"
Corpo della risposta
{
"error": {
"code": 401,
"message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
"errors": [
{
"message": "Invalid Credentials",
"domain": "global",
"reason": "authError",
"location": "Authorization",
"locationType": "header"
}
],
"status": "UNAUTHENTICATED"
}
}