Zu Google Identity Services migrieren

Überblick

Google bietet mehrere JavaScript-Bibliotheken, um ein Zugriffstoken pro Nutzer zum Aufrufen von Google APIs zu erhalten:

In diesem Leitfaden finden Sie eine Anleitung für die Migration von diesen Bibliotheken zur Google Identity Services-Bibliothek.

Wenn Sie dieser Anleitung folgen, geschieht Folgendes:

  • die verworfene Plattformbibliothek durch die Identity Services-Bibliothek ersetzen.
  • Bei Verwendung der API-Clientbibliothek entfernen Sie das verworfene Modul gapi.auth2 sowie dessen Methoden und Objekte und ersetzen sie durch entsprechende Identity Services-Äquivalente.

Eine Beschreibung der Änderungen bei der JavaScript-Bibliothek für Identity Services finden Sie in der Übersicht und unter Funktionsweise der Nutzerautorisierung. Dort finden Sie wichtige Begriffe und Konzepte.

Informationen zur Authentifizierung für die Nutzerregistrierung und -anmeldung finden Sie unter Von Google Log-in migrieren.

Autorisierungsvorgang ermitteln

Es gibt zwei mögliche Abläufe für die Nutzerautorisierung: den impliziten Vorgang und den Autorisierungscode.

Überprüfen Sie Ihre Webanwendung, um den aktuell verwendeten Autorisierungsvorgang zu ermitteln.

Hinweise, die Ihre Webanwendung den impliziten Ablauf verwendet:

  • Ihre Webanwendung ist rein browserbasiert und hat keine Back-End-Plattform.
  • Der Nutzer muss zum Aufrufen von Google APIs anwesend sein. Ihre Anwendung verwendet nur Zugriffstokens und benötigt keine Aktualisierungstokens.
  • Ihre Web-App lädt apis.google.com/js/api.js.
  • Die Implementierung basiert auf OAuth 2.0 für clientseitige Webanwendungen.
  • Ihre Anwendung verwendet entweder die Module gapi.client oder gapi.auth2 aus der Google API-Clientbibliothek für JavaScript.

Meldungen, die Ihre Webanwendung mithilfe des Vorgangs mit Autorisierungscode ausführt:

  • Ihre Implementierung basiert auf:

  • Ihre App wird sowohl im Browser des Nutzers als auch auf Ihrer Back-End-Plattform ausgeführt.

  • Ihre Back-End-Plattform hostet einen Autorisierungscode-Endpunkt.

  • Ihre Back-End-Plattform ruft Google APIs im Namen von Nutzern auf, ohne dass sie vorhanden sein müssen. Dies wird auch als Offlinemodus bezeichnet.

  • Aktualisierungstokens werden von Ihrer Back-End-Plattform verwaltet und gespeichert.

In einigen Fällen unterstützt Ihre Codebasis möglicherweise beide Abläufe.

Autorisierungsvorgang auswählen

Vor Beginn der Migration müssen Sie entscheiden, ob Sie mit dem vorhandenen Ablauf fortfahren oder einen anderen verwenden möchten.

Lesen Sie den Abschnitt Einen Autorisierungsvorgang auswählen, um die wichtigsten Unterschiede und Vor- und Nachteile der beiden Abläufe zu verstehen.

In den meisten Fällen wird der Vorgang mit Autorisierungscode empfohlen, da er die höchste Nutzersicherheit bietet. Durch die Implementierung dieses Ablaufs kann deine Plattform außerdem einfacher neue Offlinefunktionen hinzufügen, z. B. das Abrufen von Updates, um Nutzer über wichtige Änderungen an ihrem Kalender, ihren Fotos, Abos usw. zu informieren.

Wählen Sie mithilfe der Auswahlelemente unten einen Autorisierungsvorgang aus.

Impliziter Ablauf

Zugriffstoken zur Verwendung im Browser abrufen, solange der Nutzer anwesend ist.

Beispiele für implizite Abläufe zeigen Webanwendungen vor und nach der Migration zu Identity Services.

Vorgang mit Autorisierungscode

Ein von Google ausgegebener Autorisierungscode pro Nutzer wird an Ihre Back-End-Plattform gesendet, wo er dann gegen ein Zugriffstoken und ein Aktualisierungstoken ausgetauscht wird.

Die Beispiele für den Autorisierungscodefluss zeigen Webanwendungen vor und nach der Migration zu Identity Services.

Folgen Sie in diesem Leitfaden den fett gedruckten Anleitungen zum Hinzufügen, Entfernen, Aktualisieren oder Ersetzen.

Änderungen an Ihrer browserinternen Web-App

In diesem Abschnitt werden die Änderungen beschrieben, die Sie an der browserinternen Webanwendung bei der Migration zur JavaScript-Bibliothek von Google Identity Services vornehmen.

Betroffenen Code identifizieren und Tests durchführen

Ein Cookie zur Fehlerbehebung kann dabei helfen, betroffenen Code zu finden und das Verhalten nach der Einstellung zu testen.

In großen oder komplexen Anwendungen kann es schwierig sein, den gesamten Code zu finden, der von der Einstellung des gapi.auth2-Moduls betroffen ist. Wenn Sie die Nutzung einer Funktion, die demnächst eingestellt wird, in der Console protokollieren möchten, setzen Sie den Wert des G_AUTH2_MIGRATION-Cookies auf informational. Fügen Sie optional einen Doppelpunkt gefolgt von einem Schlüssel/Wert-Paar hinzu, um auch im Sitzungsspeicher zu protokollieren. Prüfen Sie nach der Anmeldung und dem Erhalt von Anmeldedaten die erfassten Logs oder senden Sie sie zur späteren Analyse an ein Back-End. Beispiel: informational:showauth2use speichert Ursprung und URL unter einem Sitzungsspeicherschlüssel mit dem Namen showauth2use.

Wenn Sie das Verhalten der App prüfen möchten, wenn das Modul gapi.auth2 nicht mehr geladen wird, setzen Sie den Wert des Cookies G_AUTH2_MIGRATION auf enforced. So können Sie das Verhalten nach der Einstellung schon vor dem Datum der Durchsetzung testen.

Mögliche G_AUTH2_MIGRATION-Cookie-Werte:

  • enforced Das Modul „gapi.auth2“ wird nicht geladen.
  • informational Protokolliert die Verwendung eingestellter Funktionen in der JS-Konsole. Protokollieren Sie auch im Sitzungsspeicher, wenn ein optionaler Schlüsselname festgelegt ist: informational:key-name.

Zur Minimierung der Auswirkungen auf die Nutzer wird empfohlen, dieses Cookie zuerst lokal während der Entwicklung und beim Testen zu speichern, bevor Sie es in Produktionsumgebungen verwenden.

Bibliotheken und Module

Das Modul gapi.auth2 verwaltet die Nutzerauthentifizierung für die Anmeldung und den impliziten Vorgang für die Autorisierung. Dieses verworfene Modul sowie seine Objekte und Methoden werden durch die Google Identity Services-Bibliothek ersetzt.

Fügen Sie die Identity Services-Bibliothek zu Ihrer Webanwendung hinzu. Fügen Sie sie dazu in Ihr Dokument ein:

<script src="https://accounts.google.com/gsi/client" async defer></script>

Entfernen Sie alle Instanzen des Ladens des Moduls auth2 mit gapi.load('auth2', function).

Die Google Identity Services-Bibliothek ersetzt die Nutzung des Moduls gapi.auth2. Sie können das Modul gapi.client aus der Google API-Clientbibliothek für JavaScript weiterhin verwenden und von der automatischen Erstellung aufrufbarer JS-Methoden aus einem Discovery-Dokument, der Zusammenfassung mehrerer API-Aufrufe und der CORS-Verwaltungsfunktionen profitieren.

Kekse

Für die Nutzerautorisierung sind keine Cookies erforderlich.

Weitere Informationen dazu, wie bei der Nutzerauthentifizierung Cookies verwendet werden, finden Sie unter Von Google Log-in migrieren. Informationen dazu, wie Google Cookies für andere Google-Produkte und -Dienste verwendet, finden Sie unter Wie Google Cookies verwendet.

Anmeldedaten

Google Identity Services trennt die Nutzerauthentifizierung und -autorisierung in zwei separate Vorgänge, wobei die Nutzeranmeldedaten getrennt werden: Das ID-Token zur Identifizierung eines Nutzers wird getrennt vom Zugriffstoken zurückgegeben, das für die Autorisierung verwendet wird.

Informationen zu diesen Änderungen finden Sie unter Beispiele für Anmeldedaten.

Impliziter Ablauf

Nutzerauthentifizierung und -autorisierung trennen, indem die Nutzerprofilverwaltung aus Autorisierungsabläufen entfernt wird

Entfernen Sie diese JavaScript-Clientreferenzen für Google Log-in:

Methoden

  • GoogleUser.getBasicProfile()
  • GoogleUser.getId()

Vorgang mit Autorisierungscode

Identity Services trennt Anmeldedaten im Browser in ID-Token und Zugriffstoken. Diese Änderung gilt nicht für Anmeldedaten, die über direkte Aufrufe von Google OAuth 2.0-Endpunkten von Ihrer Back-End-Plattform oder über Bibliotheken abgerufen werden, die auf einem sicheren Server auf Ihrer Plattform ausgeführt werden, z. B. mit dem Node.js-Client der Google APIs.

Sitzungsstatus

Bisher konnten Sie mit Google Log-in den Anmeldestatus der Nutzer folgendermaßen verwalten:

Sie sind für die Verwaltung des Anmeldestatus und der Nutzersitzungen für Ihre Webanwendung verantwortlich.

Entfernen Sie diese JavaScript-Clientreferenzen für Google Log-in:

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 Webanwendung, um einen Tokenclient für den impliziten Vorgang oder den Vorgang mit Autorisierungscode zu initialisieren.

Entfernen Sie diese JavaScript-Clientreferenzen für Google Log-in:

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 Webanwendung zu konfigurieren. Folgen Sie dazu dem Beispiel unter Tokenclient initialisieren.

Ersetzen Sie Google Log-in-JavaScript-Clientverweise durch Google Identity Services:

Objekte:

  • gapi.auth2.AuthorizeConfig mit TokenClientConfig

Methoden:

  • gapi.auth2.init() mit google.accounts.oauth2.initTokenClient()

Parameter:

  • gapi.auth2.AuthorizeConfig.login_hint mit TokenClientConfig.login_hint.
  • gapi.auth2.GoogleUser.getHostedDomain() mit TokenClientConfig.hd.

Vorgang mit Autorisierungscode

Fügen Sie ein CodeClientConfig-Objekt und einen initCodeClient()-Aufruf hinzu, um Ihre Webanwendung zu konfigurieren. Folgen Sie dazu dem Beispiel unter Codeclient initialisieren.

Beim Wechsel vom impliziten zum Autorisierungscodeablauf:

Google Log-in-JavaScript-Clientreferenzen entfernen

Objekte:

  • gapi.auth2.AuthorizeConfig

Methoden:

  • gapi.auth2.init()

Parameter:

  • gapi.auth2.AuthorizeConfig.login_hint
  • gapi.auth2.GoogleUser.getHostedDomain()

Tokenanfrage

Eine Nutzergeste, z. B. das Klicken auf eine Schaltfläche, generiert eine Anfrage, die dazu führt, dass ein Zugriffstoken mit dem impliziten Ablauf direkt an den Browser des Nutzers oder an Ihre Back-End-Plattform zurückgegeben wird, nachdem ein Autorisierungscode pro Nutzer gegen ein Zugriffstoken und ein Aktualisierungstoken ausgetauscht wird.

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 Touch-Geste des Nutzers erforderlich, um ein Zugriffstoken anzufordern, auch wenn es eine vorherige Anfrage gab.

Ersetzen Sie Google Log-in-JavaScript-Clientreferenzen durch Google Identity Services:

Methoden:

  • gapi.auth2.authorize() mit TokenClient.requestAccessToken()
  • GoogleUser.reloadAuthResponse() mit TokenClient.requestAccessToken()

Fügen Sie einen Link oder eine Schaltfläche hinzu, um requestAccessToken() aufzurufen und den UX-Pop-up-Vorgang zu starten, um ein Zugriffstoken anzufordern oder nach Ablauf des vorhandenen Tokens ein neues Token zu erhalten.

Aktualisieren Sie Ihre Codebasis auf:

  • Lösen Sie den OAuth 2.0-Tokenvorgang mit requestAccessToken() aus.
  • Unterstützen Sie die inkrementelle Autorisierung, indem Sie requestAccessToken und OverridableTokenClientConfig 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, müssen Sie möglicherweise strukturelle Änderungen an Ihrer Codebasis vornehmen, um den Zugriff auf Bereiche nur dann anzufordern, wenn sie nicht alle auf einmal benötigt werden. Dies wird als inkrementelle Autorisierung bezeichnet. Jede Anfrage sollte so wenige Bereiche wie möglich und idealerweise einen einzelnen Bereich enthalten. Weitere Informationen zum Aktualisieren Ihrer Anwendung für die inkrementelle Autorisierung finden Sie unter Umgang mit der Nutzereinwilligung.

Wenn ein Zugriffstoken abläuft, ruft das Modul gapi.auth2 automatisch ein neues, gültiges Zugriffstoken für Ihre Webanwendung ab. Zur Verbesserung der Nutzersicherheit wird dieser automatische Tokenaktualisierungsprozess von der Google Identity Services-Bibliothek nicht unterstützt. Ihre Webanwendung muss aktualisiert werden, um ein abgelaufenes Zugriffstoken zu erkennen und ein neues anzufordern. Weitere Informationen finden Sie unten im Abschnitt „Umgang mit Tokens“.

Vorgang mit Autorisierungscode

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-Codefluss auslösen.

Weitere Informationen zum Umgang mit abgelaufenen oder widerrufenen Zugriffstokens finden Sie im Abschnitt "Tokenbehandlung" weiter unten.

Tokenbehandlung

Add-Fehlerbehandlung, um fehlgeschlagene Google API-Aufrufe zu erkennen, wenn ein abgelaufenes oder widerrufenes Zugriffstoken verwendet wird, und um ein neues, gültiges Zugriffstoken anzufordern.

Die HTTP-Statuscodes 401 Unauthorized und invalid_token werden von Google APIs zurückgegeben, wenn ein abgelaufenes oder widerrufenes Zugriffstoken verwendet wird. Ein Beispiel finden Sie unter Ungültige Tokenantwort.

Abgelaufene Tokens

Zugriffstokens sind kurzlebig und oft nur für wenige Minuten gültig.

Widerruf von Tokens

Ein Google-Kontoinhaber kann eine zuvor erteilte Einwilligung jederzeit widerrufen. Dadurch werden vorhandene Zugriffstokens und Aktualisierungstokens ungültig. Der Widerruf kann von Ihrer Plattform mit revoke() oder über ein Google-Konto ausgelöst werden.

Ersetzen Sie Google Log-in-JavaScript-Clientreferenzen durch Google Identity Services:

Methoden:

  • getAuthInstance().disconnect() mit google.accounts.oauth2.revoke()
  • GoogleUser.disconnect() mit google.accounts.oauth2.revoke()

Rufen Sie revoke auf, wenn ein Nutzer sein Konto auf Ihrer Plattform löscht oder seine Einwilligung zur Weitergabe von Daten an Ihre App widerrufen möchte.

Google zeigt dem Nutzer einen Dialog zur Einholung von Einwilligungen an, wenn Ihre Web-App oder Ihre Back-End-Plattform ein Zugriffstoken anfordert. Sehen Sie sich Beispiele für Dialogfelder zur Einholung von Einwilligungen an, die Google den Nutzern angezeigt hat.

Bevor ein Zugriffstoken für Ihre Anwendung ausgestellt wird, ist eine aktive Google-Sitzung erforderlich, um die Einwilligung des Nutzers einzuholen und das Ergebnis aufzuzeichnen. Der Nutzer muss sich möglicherweise bei einem Google-Konto anmelden, wenn noch keine Sitzung eingerichtet wurde.

Nutzer anmelden

Nutzer können in einem separaten Browsertab oder nativ über einen Browser oder ein Betriebssystem in einem Google-Konto angemeldet werden. Wir empfehlen, deiner Website Über Google anmelden hinzuzufügen, um beim ersten Öffnen deiner App eine aktive Sitzung zwischen einem Google-Konto und dem Browser einzurichten. Das bietet folgende Vorteile:

  • Minimiert die Häufigkeit, mit der sich ein Nutzer anmelden muss. Wenn ein Zugriffstoken angefordert wird, wird der Anmeldeprozess für das Google-Konto initiiert, wenn noch keine aktive Sitzung vorhanden ist.
  • Du kannst das Feld Anmeldedaten email des JWT-ID-Tokens direkt als Wert des Parameters login_hint in CodeClientConfig- oder TokenClientConfig-Objekten verwenden. Dies ist besonders hilfreich, wenn Ihre Plattform kein System zur Nutzerkontenverwaltung hat.
  • Suchen Sie nach einem Google-Konto und verknüpfen Sie es mit einem vorhandenen lokalen Nutzerkonto auf Ihrer Plattform, um doppelte Konten auf Ihrer Plattform zu minimieren.
  • Wenn ein neues lokales Konto erstellt wird, können die Dialogfelder und der Ablauf für die Anmeldung klar von den Dialogfeldern und Abläufen zur Nutzerauthentifizierung getrennt werden. Dadurch wird die Anzahl der erforderlichen Schritte reduziert und die Abbruchrate verbessert.

Nach der Anmeldung und bevor ein Zugriffstoken ausgestellt wird, müssen Nutzer Ihrer Anwendung für die angeforderten Bereiche zustimmen.

Nach der Einwilligung wird ein Zugriffstoken zusammen mit einer Liste der vom Nutzer genehmigten oder abgelehnten Bereiche zurückgegeben.

Detaillierte Berechtigungen ermöglichen es Nutzern, einzelne Bereiche zu genehmigen oder abzulehnen. Wenn Sie Zugriff auf mehrere Bereiche anfordern, wird jeder Bereich unabhängig von den anderen Bereichen gewährt oder abgelehnt. Je nach Auswahl des Nutzers aktiviert Ihre Anwendung selektiv Funktionen, die von einem individuellen Umfang abhängen.

Impliziter Ablauf

Ersetzen Sie Google Log-in-JavaScript-Clientverweise durch Google Identity Services:

Objekte:

  • gapi.auth2.AuthorizeResponse mit TokenClient.TokenResponse
  • gapi.auth2.AuthResponse mit TokenClient.TokenResponse

Methoden:

  • GoogleUser.hasGrantedScopes() mit google.accounts.oauth2.hasGrantedAllScopes()
  • GoogleUser.getGrantedScopes() mit google.accounts.oauth2.hasGrantedAllScopes()

Entfernen Sie die JavaScript-Clientreferenzen für Google Log-in:

Methoden:

  • GoogleUser.getAuthResponse()

Aktualisieren Sie Ihre Webanwendung mit hasGrantedAllScopes() und hasGrantedAnyScope(). Folgen Sie dazu diesem detaillierten Berechtigungsbeispiel.

Vorgang mit Autorisierungscode

Aktualisieren oder fügen Sie einen Autorisierungscodeendpunkt zu Ihrer Back-End-Plattform hinzu. Folgen Sie dazu der Anleitung unter Handhabung von Autorisierungscode.

Aktualisieren Sie Ihre Plattform. Folgen Sie dazu den Schritten im Leitfaden Codemodell verwenden, um die Anfrage zu validieren sowie ein Zugriffstoken und ein Aktualisierungstoken abzurufen.

Aktualisieren Sie Ihre Plattform, um Features und Funktionalität basierend auf den vom Nutzer genehmigten einzelnen Bereichen selektiv zu aktivieren oder zu deaktivieren. Folgen Sie dazu der Anleitung für die inkrementelle Autorisierung und die Untersuchung der vom Nutzer gewährten Zugriffsbereiche.

Beispiele für impliziten Fluss

Früher

GAPI-Clientbibliothek

Beispiel für die Ausführung der Google API-Clientbibliothek für JavaScript im Browser mit einem Pop-up-Dialogfeld für die Nutzereinwilligung

Das Modul gapi.auth2 wird von gapi.client.init() automatisch geladen und verwendet und ist somit 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 im Browser mit einem Pop-up-Dialogfeld für die Nutzereinwilligung.

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 API Console.
    // 'scope' field specifies space-delimited list of access scopes.
    gapi.client.init({
        'apiKey': 'YOUR_API_KEY',
        'clientId': 'YOUR_CLIENT_ID',
        'discoveryDocs': [discoveryUrl],
        'scope': SCOPE
    }).then(function () {
      GoogleAuth = gapi.auth2.getAuthInstance();

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

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

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

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

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

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

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

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

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

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

OAuth 2.0-Endpunkte

OAuth 2.0 für clientseitige Webanwendungen, die im Browser ausgeführt werden, leitet für die Nutzereinwilligung an Google weiter.

In diesem Beispiel werden direkte Aufrufe an die OAuth 2.0-Endpunkte von Google vom Browser des Nutzers aus gezeigt. Das Modul gapi.auth2 und keine JavaScript-Bibliothek werden dabei 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>

Die neue Art

Nur GIS

Dieses Beispiel zeigt nur die JavaScript-Bibliothek des Google Identity Service, die das Tokenmodell verwendet, und ein Pop-up-Dialogfeld für die Nutzereinwilligung. Sie soll die Mindestanzahl der Schritte veranschaulichen, die erforderlich sind, um einen Client zu konfigurieren, ein Zugriffstoken anzufordern und abzurufen sowie eine Google API aufzurufen.

<!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 Service-Bibliothek mithilfe des Tokenmodells hinzufügen, das Modul gapi.auth2 entfernen und eine API über die Google API-Clientbibliothek für JavaScript aufrufen.

Promise-Objekte, „async“ und „await“ werden verwendet, um die Ladereihenfolge von Bibliotheken zu erzwingen und Autorisierungsfehler abzufangen und zu wiederholen. Ein API-Aufruf wird erst ausgeführt, wenn ein gültiges Zugriffstoken verfügbar ist.

Nutzer sollen beim ersten Laden der Seite auf die Schaltfläche „Kalender anzeigen“ klicken, wenn das Zugriffstoken fehlt, oder später, nachdem das Zugriffstoken abgelaufen ist.

<!DOCTYPE html>
<html>
<head></head>
<body>
  <h1>GAPI with GIS async/await</h1>
  <button id="showEventsBtn" onclick="showEvents();">Show Calendar</button><br><br>
  <button id="revokeBtn" onclick="revokeToken();">Revoke access token</button>

  <script>

    const gapiLoadPromise = new Promise((resolve, reject) => {
      gapiLoadOkay = resolve;
      gapiLoadFail = reject;
    });
    const gisLoadPromise = new Promise((resolve, reject) => {
      gisLoadOkay = resolve;
      gisLoadFail = reject;
    });

    var tokenClient;

    (async () => {
      document.getElementById("showEventsBtn").style.visibility="hidden";
      document.getElementById("revokeBtn").style.visibility="hidden";

      // First, load and initialize the gapi.client
      await gapiLoadPromise;
      await new Promise((resolve, reject) => {
        // NOTE: the 'auth2' module is no longer loaded.
        gapi.load('client', {callback: resolve, onerror: reject});
      });
      await 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');
      });

      // Now load the GIS client
      await gisLoadPromise;
      await new Promise((resolve, reject) => {
        try {
          tokenClient = google.accounts.oauth2.initTokenClient({
              client_id: 'YOUR_CLIENT_ID',
              scope: 'https://www.googleapis.com/auth/calendar.readonly',
              prompt: 'consent',
              callback: '',  // defined at request time in await/promise scope.
          });
          resolve();
        } catch (err) {
          reject(err);
        }
      });

      document.getElementById("showEventsBtn").style.visibility="visible";
      document.getElementById("revokeBtn").style.visibility="visible";
    })();

    async function getToken(err) {

      if (err.result.error.code == 401 || (err.result.error.code == 403) &&
          (err.result.error.status == "PERMISSION_DENIED")) {

        // The access token is missing, invalid, or expired, prompt for user consent to obtain one.
        await new Promise((resolve, reject) => {
          try {
            // Settle this promise in the response callback for requestAccessToken()
            tokenClient.callback = (resp) => {
              if (resp.error !== undefined) {
                reject(resp);
              }
              // GIS has automatically updated gapi.client with the newly issued access token.
              console.log('gapi.client access token: ' + JSON.stringify(gapi.client.getToken()));
              resolve(resp);
            };
            tokenClient.requestAccessToken();
          } catch (err) {
            console.log(err)
          }
        });
      } else {
        // Errors unrelated to authorization: server errors, exceeding quota, bad requests, and so on.
        throw new Error(err);
      }
    }

    function showEvents() {

      // Try to fetch a list of Calendar events. If a valid access token is needed,
      // prompt to obtain one and then retry the original request.
      gapi.client.calendar.events.list({ 'calendarId': 'primary' })
      .then(calendarAPIResponse => console.log(JSON.stringify(calendarAPIResponse)))
      .catch(err  => getToken(err))  // for authorization errors obtain an access token
      .then(retry => gapi.client.calendar.events.list({ 'calendarId': 'primary' }))
      .then(calendarAPIResponse => console.log(JSON.stringify(calendarAPIResponse)))
      .catch(err  => console.log(err)); // cancelled by user, timeout, etc.
    }

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

  </script>

  <script async defer src="https://apis.google.com/js/api.js" onload="gapiLoadOkay()" onerror="gapiLoadFail(event)"></script>
  <script async defer src="https://accounts.google.com/gsi/client" onload="gisLoadOkay()" onerror="gisLoadFail(event)"></script>

</body>
</html>

GAPI-Callback

In diesem Beispiel wird gezeigt, wie Sie die Google Identity Service-Bibliothek mithilfe des Tokenmodells hinzufügen, das Modul gapi.auth2 entfernen und eine API über die Google API-Clientbibliothek für JavaScript aufrufen.

Variablen werden verwendet, um die Ladereihenfolge von Bibliotheken zu erzwingen. GAPI-Aufrufe erfolgen innerhalb des Callbacks, nachdem ein gültiges Zugriffstoken zurückgegeben wurde.

Es wird erwartet, dass Nutzer beim ersten Laden der Seite auf die Schaltfläche „Kalender anzeigen“ klicken 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 Ablauf mit Autorisierungscode

Das Pop-up der Google Identity Service Library kann entweder eine URL-Weiterleitung verwenden, um einen Autorisierungscode direkt an den Back-End-Token-Endpunkt zurückzugeben, oder einen JavaScript-Callback-Handler, der im Browser des Nutzers ausgeführt wird und die Antwort an Ihre Plattform weiterleitet. In beiden Fällen führt Ihre Back-End-Plattform den OAuth 2.0-Vorgang aus, um ein gültiges Aktualisierungs- und Zugriffstoken zu erhalten.

Früher

Serverseitige Webanwendungen

Google Log-in für serverseitige Anwendungen, die auf der Back-End-Plattform ausgeführt werden, und zwar mithilfe einer Weiterleitung an Google für die Nutzereinwilligung.

<!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 Autorisierungscode vom Browser des Nutzers an Ihre Back-End-Plattform zu senden. Die Nutzereinwilligung wird gehandhabt, indem der Browser des Nutzers an Google weitergeleitet wird.

/\*
 \* 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 &lt;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();
}

Die neue Art

UX für GIS-Pop-up

Dieses Beispiel zeigt nur die JavaScript-Bibliothek des Google Identity Service, die das Autorisierungscodemodell verwendet. Es wird ein Pop-up-Dialogfeld für die Nutzereinwilligung und ein Callback-Handler für den Empfang des Autorisierungscodes von Google angezeigt. Sie soll die Mindestanzahl der Schritte veranschaulichen, die erforderlich sind, um einen Client zu konfigurieren, die Einwilligung einzuholen und einen Autorisierungscode an Ihre Back-End-Plattform zu senden.

<!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 für GIS-Weiterleitung

Das Autorisierungscode-Modell unterstützt das Pop-up- und Weiterleitungs-UX-Modus, um einen Autorisierungscode pro Nutzer an den von Ihrer Plattform gehosteten Endpunkt zu senden. Der UX-Weiterleitungsmodus wird hier dargestellt:

<!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 konsolidiert und ersetzt Funktionen, die in verschiedenen Bibliotheken und Modulen zu finden sind:

Aktionen 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 Vorgang mit Autorisierungscode hinzu.

Kurzübersicht für Mediathek

Objekt- und Methodenvergleich zwischen der alten Google Log-in-JavaScript-Clientbibliothek und der neuen Bibliothek Google Identity Services sowie Notes mit zusätzlichen Informationen und Maßnahmen während der Migration.

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 Alte durch neue ersetzen. Der Widerruf kann auch über https://myaccount.google.com/permissions erfolgen.
GoogleAuth.grantOfflineAccess() Entfernen Sie den Autorisierungscode und folgen Sie dem Ablauf für den Autorisierungscode.
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 Alte durch neue ersetzen. Der Widerruf kann auch über https://myaccount.google.com/permissions erfolgen.
GoogleUser.getAuthResponse() requestCode() or requestAccessToken() Altes durch neues ersetzen
GoogleUser.getBasicProfile() Entfernen Verwenden Sie stattdessen ein ID-Token. Weitere Informationen dazu finden Sie im Hilfeartikel Von Google Log-in migrieren.
GoogleUser.getGrantedScopes() hasGrantedAnyScope() Altes durch neues ersetzen
GoogleUser.getHostedDomain() Entfernen
GoogleUser.getId() Entfernen
GoogleUser.grantOfflineAccess() Entfernen Sie den Autorisierungscode und folgen Sie dem Ablauf für den Autorisierungscode.
GoogleUser.grant() Entfernen
GoogleUser.hasGrantedScopes() hasGrantedAnyScope() Altes durch neues ersetzen
GoogleUser.isSignedIn() Entfernen
GoogleUser.reloadAuthResponse() requestAccessToken() Entfernen Sie das alte. Rufen Sie „neu“ auf, um ein abgelaufenes oder widerrufenes Zugriffstoken zu ersetzen.
gapi.auth2 -Objekt und zugehörige Methoden:
Objekt „gapi.auth2.AuthorizeConfig“ TokenClientConfig oder CodeClientConfig Altes durch neues ersetzen
Objekt „gapi.auth2.AuthorizeResponse“ Entfernen
Objekt gapi.auth2.AuthResponse Entfernen
gapi.auth2.authorize() requestCode() or requestAccessToken() Altes durch neues ersetzen
gapi.auth2.ClientConfig() TokenClientConfig oder CodeClientConfig Altes durch neues ersetzen
gapi.auth2.getAuthInstance() Entfernen
gapi.auth2.init() initTokenClient() or initCodeClient() Altes durch neues ersetzen
Objekt „gapi.auth2.OfflineAccessOptions“ Entfernen
Objekt „gapi.auth2.SignInOptions“ Entfernen
gapi.signin2 und zugehörige Methoden:
gapi.signin2.render() Entfernen Das Laden des HTML-DOM-Elements g_id_signin oder des JS-Aufrufs von google.accounts.id.renderButton löst die Nutzeranmeldung in einem Google-Konto aus.

Beispiel für Anmeldedaten

Vorhandene Anmeldedaten

Die Bibliothek der Google Log-in-Plattform, die Google API-Clientbibliothek für JavaScript oder direkte Aufrufe an Google Auth 2.0-Endpunkte geben in einer Antwort sowohl ein OAuth 2.0-Zugriffstoken als auch ein OpenID Connect-ID-Token zurück.

Beispielantwort, die access_token und id_token enthält:

  {
    "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 für die 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 Token-Antwort

Beispielantwort von Google bei dem Versuch, 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"
    }
  }