Übersicht
Google bietet mehrere JavaScript-Bibliotheken an, um ein Zugriffstoken pro Nutzer zum Aufrufen von Google APIs zu erhalten:
In dieser Anleitung wird beschrieben, wie Sie von diesen Bibliotheken zur Google Identity Services-Bibliothek migrieren.
Wenn Sie dieser Anleitung folgen, werden Sie:
- Ersetzen Sie die eingestellte Plattformbibliothek durch die Identity Services-Bibliothek.
- Wenn Sie die API-Clientbibliothek verwenden, entfernen Sie das eingestellte Modul
gapi.auth2
, seine Methoden und Objekte und ersetzen Sie sie durch die entsprechenden Identity Services-Elemente.
Eine Beschreibung der Änderungen an der Identity Services JavaScript-Bibliothek finden Sie in der Übersicht. Informationen zu wichtigen Begriffen und Konzepten finden Sie unter Funktionsweise der Nutzerautorisierung.
Wenn Sie die Authentifizierung für die Registrierung und Anmeldung von Nutzern benötigen, lesen Sie stattdessen den Abschnitt Von Google Log-in migrieren.
Autorisierungsablauf ermitteln
Es gibt zwei mögliche Nutzerautorisierungsabläufe: implizit und Autorisierungscode.
Überprüfen Sie Ihre Webanwendung, um den verwendeten Autorisierungsablauf zu ermitteln.
Hinweise darauf, dass Ihre Web-App den impliziten Ablauf verwendet:
- Ihre Web-App basiert ausschließlich auf dem Browser und hat keine Backend-Plattform.
- Der Nutzer muss anwesend sein, um Google-APIs aufzurufen. Ihre App verwendet nur Zugriffstokens und benötigt keine Aktualisierungstokens.
- Ihre Web-App wird geladen
apis.google.com/js/api.js
. - Ihre Implementierung basiert auf OAuth 2.0 für clientseitige Webanwendungen.
- Ihre App verwendet entweder die Module
gapi.client
odergapi.auth2
aus der Google API-Clientbibliothek für JavaScript.
Hinweise darauf, dass Ihre Webanwendung den Autorisierungscode-Vorgang verwendet:
Ihre Implementierung basiert auf:
Ihre App wird sowohl im Browser des Nutzers als auch auf Ihrer Backend-Plattform ausgeführt.
Ihre Backend-Plattform hostet einen Autorisierungscode-Endpunkt.
Ihre Backend-Plattform ruft Google-APIs im Namen von Nutzern auf, ohne dass diese anwesend sein müssen. Dies wird auch als Offlinemodus bezeichnet.
Aktualisierungstokens werden von Ihrer Backend-Plattform verwaltet und gespeichert.
In einigen Fällen unterstützt Ihre Codebasis möglicherweise beide Abläufe.
Autorisierungsablauf auswählen
Bevor Sie mit der Migration beginnen, müssen Sie entscheiden, ob Sie Ihren bestehenden Ablauf beibehalten oder einen anderen Ablauf verwenden möchten.
Unter Autorisierungsablauf auswählen finden Sie Informationen zu den wichtigsten Unterschieden und Kompromissen zwischen den beiden Abläufen.
In den meisten Fällen wird der Autorisierungscode-Vorgang empfohlen, da er das höchste Maß an Nutzersicherheit bietet. Durch die Implementierung dieses Ablaufs kann Ihre Plattform auch neue Offlinefunktionen hinzufügen, z. B. das Abrufen von Updates, um Nutzer über wichtige Änderungen an ihrem Kalender, ihren Fotos und ihren Abos zu informieren.
Wählen Sie mithilfe der Auswahlfelder einen Autorisierungsablauf aus.
Impliziter Ablauf
Zugriffstoken für die Verwendung im Browser abrufen, während der Nutzer anwesend ist
Unter Beispiele für den impliziten Ablauf sehen Sie Web-Apps vor und nach der Migration zu Identity Services.
Autorisierungscode-Ablauf
Ein von Google ausgestellter Autorisierungscode pro Nutzer wird an Ihre Backend-Plattform gesendet, wo er dann gegen ein Zugriffstoken und ein Aktualisierungstoken eingetauscht wird.
Unter Beispiele für den Autorisierungscode-Ablauf sehen Sie Web-Apps vor und nach der Migration zu Identity Services.
Folgen Sie in dieser Anleitung den fett gedruckten Anweisungen, um vorhandene Funktionen zu hinzuzufügen, entfernen, aktualisieren oder ersetzen.
Änderungen an Ihrer In-Browser-Web-App
In diesem Abschnitt werden die Änderungen beschrieben, die Sie an Ihrer In-Browser-Web-App vornehmen müssen, wenn Sie zur Google Identity Services-JavaScript-Bibliothek migrieren.
Betroffenen Code ermitteln und testen
Ein Debug-Cookie kann helfen, betroffenen Code zu finden und das Verhalten nach der Einstellung zu testen.
Bei großen oder komplexen Apps kann es schwierig sein, den gesamten Code zu finden, der von der Einstellung des gapi.auth2
-Moduls betroffen ist. Wenn Sie die vorhandene Verwendung von Funktionen, die bald eingestellt werden, in der Konsole protokollieren möchten, legen Sie den Wert des Cookies G_AUTH2_MIGRATION
auf informational
fest. Optional können Sie einen Doppelpunkt gefolgt von einem Schlüsselwert hinzufügen, um auch im Sitzungsspeicher zu protokollieren. Nach der Anmeldung und dem Empfang von Anmeldedaten werden die erfassten Protokolle zur späteren Analyse an ein Backend gesendet. Mit informational:showauth2use
werden beispielsweise der Ursprung und die URL in einem Sitzungsspeicherschlüssel mit dem Namen showauth2use
gespeichert.
Wenn Sie das Verhalten der App prüfen möchten, wenn das gapi.auth2
-Modul nicht mehr geladen wird, legen Sie den Wert des G_AUTH2_MIGRATION
-Cookies auf enforced
fest. So können Sie das Verhalten nach der Einstellung vor dem Datum der Erzwingung testen.
Mögliche G_AUTH2_MIGRATION
-Cookie-Werte:
enforced
Das Modulgapi.auth2
wird nicht geladen.informational
Verwendung eingestellter Funktionen in der JS-Konsole protokollieren. Außerdem wird im Sitzungsspeicher protokolliert, wenn ein optionaler Schlüsselname festgelegt ist:informational:key-name
.
Um die Auswirkungen auf Nutzer zu minimieren, empfehlen wir, dieses Cookie zuerst lokal während der Entwicklung und des Tests festzulegen, bevor Sie es in Produktionsumgebungen verwenden.
Bibliotheken und Module
Das gapi.auth2
-Modul verwaltet die Nutzerauthentifizierung für die Anmeldung und den impliziten Ablauf für die Autorisierung. Ersetzen Sie dieses eingestellte Modul sowie seine Objekte und Methoden durch die Google Identity Services-Bibliothek.
Fügen Sie die Identity Services-Bibliothek Ihrer Web-App hinzu, indem Sie sie in Ihr Dokument einfügen:
<script src="https://accounts.google.com/gsi/client" async defer></script>
Entfernen Sie alle Instanzen des Ladens des auth2
-Moduls mit gapi.load('auth2',
function)
.
Die Google Identity Services-Bibliothek ersetzt die Verwendung des gapi.auth2
-Moduls.
Sie können das gapi.client
-Modul aus der Google API Client Library for JavaScript weiterhin verwenden und die automatische Erstellung aufrufbarer JS-Methoden aus einem Discovery-Dokument, das Batching mehrerer API-Aufrufe und die CORS-Verwaltungsfunktionen nutzen.
Kekse
Für die Nutzerautorisierung ist die Verwendung von Cookies nicht erforderlich.
Weitere Informationen dazu, wie bei der Nutzerauthentifizierung Cookies verwendet werden, finden Sie unter Von Google Log-in migrieren. Informationen zur Verwendung von Cookies durch andere Google-Produkte und ‑Dienste finden Sie unter Wie Google Cookies verwendet.
Anmeldedaten
Bei Google Identity Services werden Nutzerauthentifizierung und ‑autorisierung in zwei separate Vorgänge unterteilt und Nutzeranmeldedaten sind getrennt: Das ID-Token, das zur Identifizierung eines Nutzers verwendet wird, wird separat vom Zugriffstoken zurückgegeben, das zur Autorisierung verwendet wird.
Impliziter Ablauf
Trennen Sie die Nutzerauthentifizierung und ‑autorisierung, indem Sie die Verarbeitung von Nutzerprofilen aus Autorisierungsabläufen entfernen.
Entfernen Sie diese Referenzen zum Google Log-in-JavaScript-Client:
Methoden
GoogleUser.getBasicProfile()
GoogleUser.getId()
Autorisierungscode-Ablauf
Identity Services trennt Anmeldedaten im Browser in ID-Token und Zugriffstoken. Diese Änderung gilt nicht für Anmeldedaten, die durch direkte Aufrufe von Google OAuth 2.0-Endpunkten von Ihrer Backend-Plattform oder über Bibliotheken, die auf einem sicheren Server auf Ihrer Plattform ausgeführt werden, wie z. B. den Google APIs Node.js Client, abgerufen werden.
Sitzungsstatus
Bisher konnten Sie mit Google Log-in den Anmeldestatus von Nutzern so verwalten:
- Callback-Handler für Überwachen des Sitzungsstatus des Nutzers.
- Listener für Ereignisse und Änderungen am Anmeldestatus für das Google-Konto eines Nutzers.
Sie sind für die Verwaltung des Anmeldestatus und der Nutzersitzungen für Ihre Web-App verantwortlich.
Entfernen Sie diese Referenzen zum Google Log-in-JavaScript-Client:
Objekte:
gapi.auth2.SignInOptions
Methoden:
GoogleAuth.attachClickHandler()
GoogleAuth.isSignedIn()
GoogleAuth.isSignedIn.get()
GoogleAuth.isSignedIn.listen()
GoogleAuth.signIn()
GoogleAuth.signOut()
GoogleAuth.currentUser.get()
GoogleAuth.currentUser.listen()
GoogleUser.isSignedIn()
Clientkonfiguration
Aktualisieren Sie Ihre Web-App, um einen Token-Client für den impliziten oder Autorisierungscode-Ablauf zu initialisieren.
Entfernen Sie diese Referenzen zum Google Log-in-JavaScript-Client:
Objekte:
gapi.auth2.ClientConfig
gapi.auth2.OfflineAccessOptions
Methoden:
gapi.auth2.getAuthInstance()
GoogleUser.grant()
Impliziter Ablauf
Fügen Sie ein TokenClientConfig
-Objekt und einen initTokenClient()
-Aufruf hinzu, um Ihre Web-App zu konfigurieren. Folgen Sie dabei dem Beispiel unter Token-Client initialisieren.
Ersetzen Sie Google Log-in-JavaScript-Clientreferenzen durch Google Identity Services:
Objekte:
gapi.auth2.AuthorizeConfig
mitTokenClientConfig
Methoden:
gapi.auth2.init()
mitgoogle.accounts.oauth2.initTokenClient()
Parameter:
gapi.auth2.AuthorizeConfig.login_hint
mitTokenClientConfig.login_hint
.gapi.auth2.GoogleUser.getHostedDomain()
mitTokenClientConfig.hd
.
Autorisierungscode-Ablauf
Fügen Sie ein CodeClientConfig
-Objekt und einen initCodeClient()
-Aufruf hinzu, um Ihre Web-App zu konfigurieren. Folgen Sie dabei dem Beispiel unter Code-Client initialisieren.
Beim Wechsel vom impliziten zum Autorisierungscode-Ablauf gilt Folgendes:
Entfernen von Referenzen zum Google Log-in-JavaScript-Client
Objekte:
gapi.auth2.AuthorizeConfig
Methoden:
gapi.auth2.init()
Parameter:
gapi.auth2.AuthorizeConfig.login_hint
gapi.auth2.GoogleUser.getHostedDomain()
Tokenanfrage
Durch eine Nutzeraktion, z. B. einen Klick auf eine Schaltfläche, wird eine Anfrage generiert, die dazu führt, dass ein Zugriffstoken direkt an den Browser des Nutzers zurückgegeben wird (beim impliziten Ablauf) oder an Ihre Backend-Plattform, nachdem ein Autorisierungscode pro Nutzer gegen ein Zugriffstoken und ein Aktualisierungstoken eingetauscht wurde.
Impliziter Ablauf
Zugriffstokens können im Browser abgerufen und verwendet werden, während der Nutzer angemeldet ist und eine aktive Sitzung mit Google hat. Im impliziten Modus ist eine Nutzeraktion erforderlich, um ein Zugriffstoken anzufordern, auch wenn zuvor eine Anfrage gestellt wurde.
Ersetzen Sie Referenzen zum Google Log-in-JavaScript-Client durch Google Identity Services:
Methoden:
gapi.auth2.authorize()
mitTokenClient.requestAccessToken()
GoogleUser.reloadAuthResponse()
mitTokenClient.requestAccessToken()
Fügen Sie einen Link oder eine Schaltfläche hinzu, um requestAccessToken()
aufzurufen und den Pop-up-UX-Ablauf zum Anfordern eines Zugriffstokens zu starten oder ein neues Token abzurufen, wenn das vorhandene Token abläuft.
Aktualisieren Sie Ihre Codebasis, damit Folgendes möglich ist:
- OAuth 2.0-Tokenvorgang mit
requestAccessToken()
auslösen. - Unterstützen Sie die inkrementelle Autorisierung, indem Sie
requestAccessToken
undOverridableTokenClientConfig
verwenden, um eine Anfrage für viele Bereiche in mehrere kleinere Anfragen aufzuteilen. - Fordern Sie ein neues Token an, wenn das vorhandene Token abläuft oder widerrufen wird.
Wenn Sie mit mehreren Bereichen arbeiten, sind möglicherweise strukturelle Änderungen an Ihrem Code erforderlich, um den Zugriff auf Bereiche nur bei Bedarf und nicht alle auf einmal anzufordern. Dies wird als inkrementelle Autorisierung bezeichnet. Jede Anfrage sollte so wenige Bereiche wie möglich und idealerweise nur einen Bereich enthalten. Weitere Informationen zum Umgang mit der Nutzereinwilligung
Wenn ein Zugriffstoken abläuft, ruft das gapi.auth2
-Modul automatisch ein neues, gültiges Zugriffstoken für Ihre Web-App ab. Aus Gründen der Nutzersicherheit wird dieser automatische Token-Aktualisierungsprozess von der Google Identity Services-Bibliothek nicht unterstützt. Ihre Web-App muss aktualisiert werden, damit sie ein abgelaufenes Zugriffstoken erkennen und ein neues anfordern kann. Weitere Informationen finden Sie im Abschnitt „Token-Verarbeitung“.
Autorisierungscode-Ablauf
Fügen Sie einen Link oder eine Schaltfläche hinzu, um requestCode()
aufzurufen und einen Autorisierungscode von Google anzufordern. Ein Beispiel finden Sie unter OAuth 2.0-Vorgang mit Autorisierungscode auslösen.
Weitere Informationen dazu, wie Sie auf ein abgelaufenes oder widerrufenes Zugriffstoken reagieren, finden Sie im Abschnitt zur Token-Verarbeitung.
Umgang mit Tokens
Fügen Sie eine Fehlerbehandlung hinzu, um fehlgeschlagene Google API-Aufrufe zu erkennen, wenn ein abgelaufenes oder widerrufenes Zugriffstoken verwendet wird, und um ein neues, gültiges Zugriffstoken anzufordern.
Ein HTTP-Statuscode von 401 Unauthorized
und die Fehlermeldung invalid_token
werden von Google-APIs zurückgegeben, wenn ein abgelaufenes oder widerrufenes Zugriffstoken verwendet wird. Ein Beispiel finden Sie unter Antwort mit ungültigem Token.
Abgelaufene Tokens
Zugriffstokens sind kurzlebig und oft nur wenige Minuten gültig.
Tokenwiderruf
Der Inhaber eines Google-Kontos kann eine zuvor erteilte Einwilligung jederzeit widerrufen. Dadurch werden vorhandene Zugriffs- und Aktualisierungstokens ungültig. Der Widerruf kann über Ihre Plattform mit revoke()
oder über ein Google-Konto ausgelöst werden.
Ersetzen Sie Referenzen zum Google Log-in-JavaScript-Client durch Google Identity Services:
Methoden:
getAuthInstance().disconnect()
mitgoogle.accounts.oauth2.revoke()
GoogleUser.disconnect()
mitgoogle.accounts.oauth2.revoke()
Rufen Sie revoke
auf, wenn ein Nutzer sein Konto auf Ihrer Plattform löscht oder die Einwilligung zum Teilen von Daten mit Ihrer App widerrufen möchte.
Aufforderung zur Nutzereinwilligung
Google zeigt dem Nutzer ein Zustimmungsdialogfeld an, wenn entweder Ihre Web-App oder Ihre Backend-Plattform ein Zugriffstoken anfordert. Beispiel für Zustimmungsdialogfelder, die Nutzern von Google angezeigt werden
Bevor ein Zugriffstoken für Ihre App ausgestellt wird, ist eine bestehende und aktive Google-Sitzung erforderlich, um die Zustimmung des Nutzers einzuholen und das Ergebnis aufzuzeichnen. Der Nutzer muss sich möglicherweise in einem Google-Konto anmelden, wenn noch keine Sitzung vorhanden ist.
Nutzer anmelden
Nutzer können in einem separaten Browsertab oder nativ über einen Browser oder ein Betriebssystem in einem Google-Konto angemeldet sein. Wir empfehlen, Mit Google anmelden auf Ihrer Website hinzuzufügen, um eine aktive Sitzung zwischen einem Google-Konto und dem Browser herzustellen, wenn der Nutzer Ihre App zum ersten Mal öffnet. Das bietet folgende Vorteile:
- Die Anzahl der Anmeldungen, die ein Nutzer durchführen muss, wird minimiert. Wenn ein Zugriffstoken angefordert wird, wird der Anmeldevorgang für das Google-Konto gestartet, falls noch keine aktive Sitzung vorhanden ist.
- Verwenden Sie das Feld credential
email
des JWT-ID-Tokens direkt als Wert des Parameterslogin_hint
inCodeClientConfig
- oderTokenClientConfig
-Objekten. Das ist besonders hilfreich, wenn Ihre Plattform kein System zur Verwaltung von Nutzerkonten hat. - Ein Google-Konto mit einem bestehenden lokalen Nutzerkonto auf Ihrer Plattform verknüpfen, um doppelte Konten auf Ihrer Plattform zu vermeiden.
- Wenn ein neues lokales Konto erstellt wird, können Ihre Registrierungsdialogfelder und ‑abläufe klar von den Dialogfeldern und ‑abläufen für die Nutzerauthentifizierung getrennt werden. Dadurch wird die Anzahl der erforderlichen Schritte verringert und die Abbruchrate verbessert.
Nach der Anmeldung und bevor ein Zugriffstoken ausgestellt wird, müssen Nutzer Ihrer Anwendung die Einwilligung für die angeforderten Bereiche erteilen.
Token- und Einwilligungsantwort
Nach der Einwilligung wird ein Zugriffstoken zusammen mit einer Liste der vom Nutzer genehmigten oder abgelehnten Bereichsanforderungen zurückgegeben.
Mit detaillierten Berechtigungen können Nutzer einzelne Bereiche genehmigen oder ablehnen. Wenn Sie Zugriff auf mehrere Bereiche anfordern, wird jeder Bereich unabhängig von den anderen Bereichen gewährt oder abgelehnt. Basierend auf der Auswahl des Nutzers werden in Ihrer App selektiv Funktionen und Features aktiviert, die von einem individuellen Bereich abhängen.
Impliziter Ablauf
Ersetzen Sie Google Log-in-JavaScript-Clientreferenzen durch Google Identity Services:
Objekte:
gapi.auth2.AuthorizeResponse
mitTokenClient.TokenResponse
gapi.auth2.AuthResponse
mitTokenClient.TokenResponse
Methoden:
GoogleUser.hasGrantedScopes()
mitgoogle.accounts.oauth2.hasGrantedAllScopes()
GoogleUser.getGrantedScopes()
mitgoogle.accounts.oauth2.hasGrantedAllScopes()
Entfernen von Referenzen zum Google Log-in-JavaScript-Client:
Methoden:
GoogleUser.getAuthResponse()
Aktualisieren Sie Ihre Web-App mit hasGrantedAllScopes()
und hasGrantedAnyScope()
. Hier finden Sie ein Beispiel für detaillierte Berechtigungen.
Autorisierungscode-Ablauf
Aktualisieren oder Fügen Sie einen Autorisierungscode-Endpunkt zu Ihrer Backend-Plattform hinzu. Folgen Sie dazu der Anleitung unter Autorisierungscode-Verarbeitung.
Aktualisieren Sie Ihre Plattform gemäß der Anleitung unter Code-Modell verwenden, um die Anfrage zu validieren und ein Zugriffs- und Aktualisierungstoken zu erhalten.
Aktualisieren Sie Ihre Plattform, um Funktionen und Features basierend auf den einzelnen Bereichen, die der Nutzer genehmigt hat, selektiv zu aktivieren oder zu deaktivieren. Folgen Sie dazu der Anleitung für die inkrementelle Autorisierung und prüfen Sie die vom Nutzer gewährten Zugriffsbereiche.
Beispiele für implizite Vorgänge
Die alte Methode
GAPI-Clientbibliothek
Beispiel für die Google API-Clientbibliothek für JavaScript, die in einem Browser mit einem Pop-up-Dialogfeld für die Einwilligung des Nutzers ausgeführt wird.
Das gapi.auth2
-Modul wird automatisch von gapi.client.init()
geladen und verwendet und ist daher ausgeblendet.
<!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>
JS-Clientbibliothek
OAuth 2.0 für clientseitige Webanwendungen, die in einem Browser ausgeführt werden und ein Pop-up-Dialogfeld für die Einwilligung des Nutzers verwenden.
Das Modul gapi.auth2
wird manuell geladen.
<!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>
OAuth 2.0-Endpunkte
OAuth 2.0 für clientseitige Webanwendungen, die im Browser ausgeführt werden und Weiterleitungen zu Google verwenden, um die Einwilligung des Nutzers einzuholen.
In diesem Beispiel werden direkte Aufrufe der OAuth 2.0-Endpunkte von Google über den Browser des Nutzers gezeigt. Das gapi.auth2
-Modul oder eine JavaScript-Bibliothek werden nicht verwendet.
<!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>
Jetzt
Nur GIS
In diesem Beispiel wird nur die JavaScript-Bibliothek des Google Identity Service mit dem Tokenmodell und dem Pop-up-Dialog für die Nutzereinwilligung gezeigt. Es soll die Mindestanzahl der Schritte veranschaulichen, die zum Konfigurieren eines Clients, zum Anfordern und Abrufen eines Zugriffstokens und zum Aufrufen einer Google API erforderlich sind.
<!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
In diesem Beispiel wird gezeigt, wie Sie die Google Identity Services-Bibliothek mit dem Tokenmodell hinzufügen, das gapi.auth2
-Modul entfernen und eine API mit der Google API-Clientbibliothek für JavaScript aufrufen.
Promises, async und await werden verwendet, um die Reihenfolge des Ladens der Bibliothek zu erzwingen und Autorisierungsfehler abzufangen und zu wiederholen. Ein API-Aufruf erfolgt erst, wenn ein gültiges Zugriffstoken verfügbar ist.
Nutzer müssen auf die Schaltfläche „Kalender anzeigen“ klicken, wenn das Zugriffstoken beim ersten Laden der Seite fehlt oder später, nachdem das Zugriffstoken abgelaufen ist.
<!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>
GAPI-Callback
In diesem Beispiel wird gezeigt, wie Sie die Google Identity Services-Bibliothek mit dem Tokenmodell hinzufügen, das gapi.auth2
-Modul entfernen und eine API mit der Google API-Clientbibliothek für JavaScript aufrufen.
Variablen werden verwendet, um die Ladereihenfolge von Bibliotheken zu erzwingen. GAPI-Aufrufe erfolgen über den Callback, nachdem ein gültiges Zugriffstoken zurückgegeben wurde.
Nutzer müssen die Schaltfläche „Kalender anzeigen“ drücken, wenn die Seite zum ersten Mal geladen wird, und noch einmal, wenn sie ihre Kalenderinformationen aktualisieren möchten.
<!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>
Beispiele für den Autorisierungscode-Ablauf
Für das Pop-up-UX der Google Identity Service-Bibliothek kann entweder eine URL-Weiterleitung verwendet werden, um einen Autorisierungscode direkt an den Backend-Token-Endpunkt zurückzugeben, oder ein JavaScript-Callback-Handler, der im Browser des Nutzers ausgeführt wird und die Antwort an Ihre Plattform weiterleitet. In beiden Fällen schließt Ihre Backend-Plattform den OAuth 2.0-Ablauf ab, um ein gültiges Aktualisierungs- und Zugriffstoken zu erhalten.
Die alte Methode
Serverseitige Web-Apps
Google Log-in für serverseitige Apps, die auf einer Backend-Plattform ausgeführt werden und eine Weiterleitung zu Google zur Einholung der Nutzereinwilligung verwenden.
<!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 mit Weiterleitung
OAuth 2.0 für Webserveranwendungen verwenden, um den Autorisierungscode vom Browser des Nutzers an Ihre Backend-Plattform zu senden. Die Nutzereinwilligung wird durch Weiterleitung des Nutzerbrowsers an Google eingeholt.
/\*
\* 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();
}
Jetzt
GIS-Pop-up-Benutzeroberfläche
In diesem Beispiel wird nur die Google Identity Services JavaScript-Bibliothek mit dem Autorisierungscode-Modell verwendet, um ein Pop-up-Dialogfeld für die Nutzereinwilligung und einen Callback-Handler zum Empfangen des Autorisierungscodes von Google zu erstellen. Es soll die Mindestanzahl der Schritte veranschaulichen, die zum Konfigurieren eines Clients, zum Einholen der Einwilligung und zum Senden eines Autorisierungscodes an Ihre Backend-Plattform erforderlich sind.
<!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>
GIS-Weiterleitung – UX
Das Autorisierungscode-Modell unterstützt die UX-Modi „Pop-up“ und „Weiterleitung“, um einen Autorisierungscode pro Nutzer an den von Ihrer Plattform gehosteten Endpunkt zu senden. Der UX-Modus für die Weiterleitung wird hier gezeigt:
<!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>
JavaScript-Bibliotheken
Google Identity Services ist eine einzelne JavaScript-Bibliothek, die für die Nutzerauthentifizierung und ‑autorisierung verwendet wird. Sie fasst Funktionen und Funktionalitäten aus verschiedenen Bibliotheken und Modulen zusammen und ersetzt sie:
Maßnahmen bei der Migration zu Identity Services:
Vorhandene JS-Bibliothek | Neue JS-Bibliothek | Hinweise |
---|---|---|
apis.google.com/js/api.js |
accounts.google.com/gsi/client |
Fügen Sie eine neue Bibliothek hinzu und folgen Sie dem impliziten Ablauf. |
apis.google.com/js/client.js |
accounts.google.com/gsi/client |
Fügen Sie eine neue Bibliothek und den Autorisierungscode-Ablauf hinzu. |
Kurzreferenz für Bibliotheken
Vergleich von Objekt und Methode zwischen der alten Google Sign-In JavaScript-Client-Bibliothek und der neuen Google Identity Services-Bibliothek sowie Hinweise mit zusätzlichen Informationen und Maßnahmen, die während der Migration zu ergreifen sind.
Alt | Neu | Hinweise |
---|---|---|
GoogleAuth -Objekt und zugehörige Methoden: | ||
GoogleAuth.attachClickHandler() | Entfernen | |
GoogleAuth.currentUser.get() | Entfernen | |
GoogleAuth.currentUser.listen() | Entfernen | |
GoogleAuth.disconnect() | google.accounts.oauth2.revoke | Ersetzen Sie das alte durch das neue. Der Widerruf kann auch über https://myaccount.google.com/permissions erfolgen. |
GoogleAuth.grantOfflineAccess() | Entfernen: Folgen Sie dem Autorisierungscode-Ablauf. | |
GoogleAuth.isSignedIn.get() | Entfernen | |
GoogleAuth.isSignedIn.listen() | Entfernen | |
GoogleAuth.signIn() | Entfernen | |
GoogleAuth.signOut() | Entfernen | |
GoogleAuth.then() | Entfernen | |
GoogleUser -Objekt und zugehörige Methoden: | ||
GoogleUser.disconnect() | google.accounts.id.revoke | Ersetzen Sie das alte durch das neue. Der Widerruf kann auch über https://myaccount.google.com/permissions erfolgen. |
GoogleUser.getAuthResponse() | requestCode() or requestAccessToken() | Alte durch neue ersetzen |
GoogleUser.getBasicProfile() | Entfernen. Verwenden Sie stattdessen ein ID-Token. Weitere Informationen finden Sie unter Von Google Log-in migrieren. | |
GoogleUser.getGrantedScopes() | hasGrantedAnyScope() | Alte durch neue ersetzen |
GoogleUser.getHostedDomain() | Entfernen | |
GoogleUser.getId() | Entfernen | |
GoogleUser.grantOfflineAccess() | Entfernen: Folgen Sie dem Autorisierungscode-Ablauf. | |
GoogleUser.grant() | Entfernen | |
GoogleUser.hasGrantedScopes() | hasGrantedAnyScope() | Alte durch neue ersetzen |
GoogleUser.isSignedIn() | Entfernen | |
GoogleUser.reloadAuthResponse() | requestAccessToken() | Entfernen Sie den alten Aufruf und rufen Sie den neuen auf, um ein abgelaufenes oder widerrufenes Zugriffstoken zu ersetzen. |
gapi.auth2 -Objekt und zugehörige Methoden: | ||
gapi.auth2.AuthorizeConfig-Objekt | TokenClientConfig oder CodeClientConfig | Alte durch neue ersetzen |
gapi.auth2.AuthorizeResponse-Objekt | Entfernen | |
gapi.auth2.AuthResponse-Objekt | Entfernen | |
gapi.auth2.authorize() | requestCode() or requestAccessToken() | Alte durch neue ersetzen |
gapi.auth2.ClientConfig() | TokenClientConfig oder CodeClientConfig | Alte durch neue ersetzen |
gapi.auth2.getAuthInstance() | Entfernen | |
gapi.auth2.init() | initTokenClient() or initCodeClient() | Alte durch neue ersetzen |
gapi.auth2.OfflineAccessOptions-Objekt | Entfernen | |
gapi.auth2.SignInOptions-Objekt | Entfernen | |
gapi.signin2 -Objekt und zugehörige Methoden: | ||
gapi.signin2.render() | Entfernen. Das Laden des HTML-DOM des Elements g_id_signin oder der JS-Aufruf von google.accounts.id.renderButton löst die Nutzeranmeldung in einem Google-Konto aus. |
Beispielanmeldedaten
Vorhandene Anmeldedaten
Die Google Sign-In-Plattformbibliothek, die Google API Client Library for JavaScript oder direkte Aufrufe von Google OAuth 2.0-Endpunkten geben sowohl ein OAuth 2.0-Zugriffstoken als auch ein OpenID Connect-ID-Token in einer einzigen Antwort zurück.
Beispielantwort mit access_token
und 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"
}
Anmeldedaten für Google Identity Services
Die Google Identity Services-Bibliothek gibt Folgendes zurück:
entweder ein Zugriffstoken, wenn es zur Autorisierung verwendet wird:
{ "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" }
oder ein ID-Token, wenn es zur Authentifizierung verwendet wird:
{ "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" }
Ungültige Tokenantwort
Beispielantwort von Google, wenn versucht wird, eine API-Anfrage mit einem abgelaufenen, widerrufenen oder ungültigen Zugriffstoken zu stellen:
HTTP-Antwortheader
www-authenticate: Bearer realm="https://accounts.google.com/", error="invalid_token"
Antworttext
{
"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"
}
}