Zu Google Identity Services migrieren

Übersicht

Google bietet mehrere JavaScript-Bibliotheken, um nutzerspezifische Zugriffstokens für den Aufruf von Google APIs zu erhalten:

Dieser Leitfaden enthält eine Anleitung für die Migration von diesen Bibliotheken zur Google Identity Services-Bibliothek.

Wenn Sie dieser Anleitung folgen, können Sie Folgendes tun:

  • ersetzen Sie die veraltete Plattformbibliothek durch die Identity Services-Bibliothek und
  • Wenn Sie die API-Clientbibliothek verwenden, entfernen Sie das eingestellte gapi.auth2-Modul, seine Methoden und Objekte und ersetzen Sie sie durch die entsprechenden Identitätsdienste.

Eine Beschreibung der Änderungen an der JavaScript-Bibliothek für Identity Services finden Sie in der Übersicht und unter Funktionsweise der Nutzerautorisierung. Dort werden auch wichtige Begriffe und Konzepte erläutert.

Informationen zur Authentifizierung bei der Nutzerregistrierung und ‑anmeldung finden Sie stattdessen unter Von Google Log-in migrieren.

Autorisierungsablauf identifizieren

Es gibt zwei mögliche Nutzerautorisierungsabläufe: implizit und Autorisierungscode.

Prüfen Sie Ihre Webanwendung, um den derzeit verwendeten Autorisierungsablauf zu ermitteln.

Anzeichen dafür, dass 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 App verwendet nur Zugriffstokens und keine Aktualisierungstokens.
  • Ihre Webanwendung lädt apis.google.com/js/api.js.
  • Ihre Implementierung basiert auf OAuth 2.0 für clientseitige Webanwendungen.
  • Ihre App verwendet entweder die gapi.client- oder die gapi.auth2-Module aus der Google API-Clientbibliothek für JavaScript.

Anzeichen dafür, dass Ihre Webanwendung den Vorgang mit Autorisierungscode verwendet:

  • Ihre Implementierung basiert auf:

  • Ihre App wird sowohl im Browser des Nutzers als auch auf Ihrer Backend-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 diese vorhanden sein müssen. Dies wird auch als Offlinemodus bezeichnet.

  • Aktualisierungstokens werden von deiner 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 mit dem vorhandenen Ablauf fortfahren oder einen anderen Ablauf verwenden sollten.

Weitere Informationen zu den wichtigsten Unterschieden und Vor- und Nachteilen der beiden Abläufe finden Sie unter Autorisierungsablauf auswählen.

In den meisten Fällen wird der Autorisierungscode-Vorgang empfohlen, da er die höchste Nutzersicherheit bietet. Wenn Sie diesen Ablauf implementieren, können Sie Ihrer Plattform auch leichter neue Offlinefunktionen hinzufügen, z. B. das Abrufen von Updates, um Nutzer über wichtige Änderungen an ihrem Kalender, ihren Fotos, ihren Abos usw. zu informieren.

Wählen Sie mithilfe der Auswahl unten einen Autorisierungsablauf aus.

Impliziter Ablauf

Ein Zugriffstoken für die Verwendung im Browser abrufen, während sich der Nutzer im Browser befindet.

Beispiele für den impliziten Ablauf zeigt Webanwendungen vor und nach der Migration zu Identity Services.

Autorisierungscode-Ablauf

Ein von Google ausgestellter Autorisierungscode pro Nutzer wird an deine Back-End-Plattform gesendet, wo er gegen ein Zugriffs- und ein Aktualisierungstoken eingetauscht wird.

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

Folgen Sie in diesem Leitfaden der fett formatierten Anleitung, um vorhandene Funktionen zu hinzufü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 identifizieren und testen

Mit einem Debug-Cookie können Sie den betroffenen Code finden und das Verhalten nach der Einstellung testen.

In großen oder komplexen Anwendungen kann es schwierig sein, den gesamten Code zu finden, der von der Einstellung des Moduls gapi.auth2 betroffen ist. Wenn Sie die Verwendung von bald eingestellten Funktionen in der Konsole protokollieren möchten, setzen Sie den Wert des G_AUTH2_MIGRATION-Cookies auf informational. Optional können Sie einen Doppelpunkt gefolgt von einem Schlüsselwert hinzufügen, um das Protokoll auch im Sitzungsspeicher zu speichern. Nach der Anmeldung und dem Erhalt der Anmeldedaten können Sie die erfassten Protokolle prüfen oder zur späteren Analyse an ein Back-End senden. informational:showauth2use speichert beispielsweise den Ursprung und die URL im Sitzungsspeicherschlüssel showauth2use.

Wenn Sie das App-Verhalten 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 Werte für das G_AUTH2_MIGRATION-Cookie:

  • enforced Modul gapi.auth2 nicht laden.
  • informational Die Verwendung eingestellter Funktionen in der JS-Konsole protokollieren. Wenn ein optionaler Schlüsselname festgelegt ist, wird auch im Sitzungsspeicher protokolliert: informational:key-name.

Um die Auswirkungen auf die Nutzer zu minimieren, sollten Sie dieses Cookie zuerst lokal während der Entwicklung und des Tests festlegen, 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 veraltete Modul und seine Objekte und Methoden durch die Google Identity Services-Bibliothek.

Fügen Sie die Identity Services-Bibliothek Ihrer Webanwendung hinzu, indem Sie sie in Ihr Dokument einfügen:

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

Entfernen Sie alle Instanzen, in denen das auth2-Modul mit gapi.load('auth2', function) geladen wird.

Die Google Identity Services-Bibliothek ersetzt die Verwendung des gapi.auth2-Moduls. Du kannst das Modul gapi.client aus der Google API-Clientbibliothek für JavaScript weiterhin bedenkenlos verwenden und von der automatischen Erstellung aufrufbarer JS-Methoden aus einem Discovery-Dokument, der Batchverarbeitung mehrerer API-Aufrufe und der CORS-Verwaltungsfunktionen profitieren.

Kekse

Für die Nutzerautorisierung ist keine Verwendung von Cookies erforderlich.

Weitere Informationen dazu, wie bei der Nutzerauthentifizierung Cookies verwendet werden, finden Sie unter Von Google Log-in migrieren. Unter So verwendet Google Cookies erfahren Sie mehr über die Verwendung von Cookies in anderen Google-Produkten und ‐Diensten.

Anmeldedaten

Bei Google Identity Services werden Nutzerauthentifizierung und Autorisierung in zwei separate Vorgänge unterteilt. Außerdem sind die Anmeldedaten getrennt: Das ID-Token, das zur Identifizierung eines Nutzers verwendet wird, wird getrennt vom Zugriffstoken zurückgegeben, das für die Autorisierung verwendet wird.

Eine Übersicht über diese Änderungen finden Sie in den Beispielanmeldedaten.

Impliziter Ablauf

Trennen Sie Nutzerauthentifizierung und Autorisierung, indem Sie die Nutzerprofilverwaltung aus den Autorisierungsabläufen entfernen.

Entfernen Sie die folgenden Referenzen zum Google Sign-in-JavaScript-Client:

Methoden

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

Autorisierungscode-Ablauf

Identitätsdienste trennen Browser-Anmeldedaten in ID-Token und Zugriffstoken. Diese Änderung gilt nicht für Anmeldedaten, die durch direkte Aufrufe an Google OAuth 2.0-Endpunkte von Ihrer Back-End-Plattform oder über Bibliotheken auf einem sicheren Server auf Ihrer Plattform wie dem Google APIs Node.js-Client bezogen wurden.

Sitzungsstatus

Bisher konnten Sie mit Google Log-in den Anmeldestatus von Nutzern mithilfe der folgenden Optionen verwalten:

Sie sind für die Verwaltung des Anmeldestatus und der Nutzersitzungen in Ihrer Webanwendung 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 Webanwendung, um einen Token-Client für den Implicit- oder Autorisierungscode-Vorgang 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 Webanwendung zu konfigurieren. Folgen Sie dazu dem Beispiel unter Tokenclient initialisieren.

Ersetzen Sie Referenzen zum Google Log-in-JavaScript-Client 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.

Autorisierungscode-Ablauf

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 Autorisierungscode-Vorgang:

Entfernen Sie Referenzen zum Google Sign-In-JavaScript-Client.

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 direkt an den Browser des Nutzers im impliziten Ablauf oder an Ihre Back-End-Plattform zurückgegeben wird, nachdem ein Autorisierungscode pro Nutzer gegen ein Zugriffstoken und ein Aktualisierungstoken ausgetauscht 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 Implicit-Modus ist eine Nutzergeste erforderlich, um ein Zugriffstoken anzufordern, auch wenn es vorher schon eine Anfrage gab.

Ersetzen Sie Referenzen zum Google Sign-in-JavaScript-Client durch Google Identity Services:

Methoden:

  • gapi.auth2.authorize() mit TokenClient.requestAccessToken()
  • GoogleUser.reloadAuthResponse() mitTokenClient.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 ein neues Token abzurufen, wenn das vorhandene Token abläuft.

Aktualisieren Sie Ihre Codebasis auf:

  • Lösche mit requestAccessToken() den OAuth 2.0-Token-Vorgang aus.
  • Sie können die inkrementelle Autorisierung unterstützen, indem Sie mit requestAccessToken und OverridableTokenClientConfig eine Anfrage für viele Bereiche in mehrere kleinere Anfragen aufteilen.
  • 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 Ihrer Codebasis erforderlich, um den Zugriff auf Bereiche nur nach Bedarf und nicht alle auf einmal anzufordern. Dies wird als inkrementelle Autorisierung bezeichnet. Jede Anfrage sollte möglichst wenige Bereiche und idealerweise nur einen Bereich enthalten. Weitere Informationen zum Aktualisieren Ihrer App für die inkrementelle Autorisierung finden Sie unter Einwilligung von Nutzern.

Wenn ein Zugriffstoken abläuft, ruft das gapi.auth2-Modul automatisch ein neues, gültiges Zugriffstoken für Ihre Webanwendung ab. Aus Sicherheitsgründen wird dieser automatische Token-Aktualisierungsprozess von der Google Identity Services-Bibliothek nicht unterstützt. Ihre Webanwendung muss aktualisiert werden, damit abgelaufene Zugriffstokens erkannt und neue angefordert werden können. Weitere Informationen finden Sie unten im Abschnitt „Umgang mit Tokens“.

Autorisierungscode-Ablauf

Fügen Sie einen Link oder eine Schaltfläche hinzu, um requestCode() aufzurufen und einen Autorisierungscode von Google anzufordern. Ein Beispiel findest du unter OAuth 2.0-Code-Flow auslösen.

Im Abschnitt zur Tokenverwaltung unten findest du weitere Informationen dazu, wie du auf ein abgelaufenes oder widerrufenes Zugriffstoken reagieren solltest.

Token-Verarbeitung

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.

Wenn ein abgelaufenes oder widerrufenes Zugriffstoken verwendet wird, geben die Google APIs den HTTP-Statuscode 401 Unauthorized und die Fehlermeldung invalid_token zurück. Ein Beispiel findest du unter Ungültige Tokenantwort.

Abgelaufene Tokens

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

Tokenwiderruf

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

Ersetzen Sie Referenzen zum Google Sign-in-JavaScript-Client 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 aufheben möchte.

Google zeigt dem Nutzer ein Einwilligungsdialogfeld an, wenn entweder Ihre Webanwendung oder Ihre Backend-Plattform ein Zugriffstoken anfordert. Beispiele für Einwilligungsdialogfelder, die von Google Nutzern angezeigt werden

Bevor ein Zugriffstoken für Ihre App ausgestellt werden kann, ist eine vorhandene und aktive Google-Sitzung erforderlich, um die Nutzereinwilligung anzufordern und das Ergebnis zu erfassen. Der Nutzer muss sich möglicherweise in 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 sein. Wir empfehlen Ihnen, Über Google anmelden auf Ihrer Website einzubinden, 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:

  • Minimiert die Anzahl der Anmeldungen, die ein Nutzer vornehmen muss. Wenn keine aktive Sitzung vorhanden ist, wird durch das Anfordern eines Zugriffstokens der Anmeldevorgang für das Google-Konto gestartet.
  • Verwende das Feld email des Anmeldedaten-JWT-ID-Tokens als Wert für den Parameter login_hint in CodeClientConfig- oder TokenClientConfig-Objekten. Das ist besonders hilfreich, wenn Ihre Plattform kein System zur Verwaltung von Nutzerkonten hat.
  • Sie können ein Google-Konto mit einem vorhandenen lokalen Nutzerkonto auf Ihrer Plattform abgleichen und verknüpfen, um doppelte Konten auf Ihrer Plattform zu minimieren.
  • Wenn ein neues lokales Konto erstellt wird, können die Dialogfelder und Abläufe für die Registrierung klar von den Dialogfeldern und Abläufen für die Nutzerauthentifizierung getrennt werden. So wird die Anzahl der erforderlichen Schritte reduziert und die Ausstiegsrate verbessert.

Nach der Anmeldung und vor der Ausstellung eines Zugriffstokens müssen Nutzer Ihrer App die angeforderten Berechtigungen erteilen.

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

Mit detaillierten Berechtigungen können Nutzer einzelne Bereiche genehmigen oder ablehnen. Wenn der Zugriff auf mehrere Bereiche angefordert wird, wird jeder Bereich unabhängig von den anderen Bereichen gewährt oder abgelehnt. Abhängig von der Auswahl des Nutzers aktiviert Ihre App selektiv Funktionen, die von einem individuellen Bereich abhängen.

Impliziter Ablauf

Ersetzen Sie Referenzen zum Google Log-in-JavaScript-Client 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 Referenzen zum Google Sign-In-JavaScript-Client:

Methoden:

  • GoogleUser.getAuthResponse()

Aktualisieren Sie Ihre Webanwendung mit hasGrantedAllScopes() und hasGrantedAnyScope() anhand dieses Beispiels für detaillierte Berechtigungen.

Autorisierungscode-Ablauf

Aktualisieren oder fügen Sie Ihrer Backend-Plattform einen Autorisierungscode-Endpunkt hinzu. Folgen Sie dazu der Anleitung unter Autorisierungscodes verarbeiten.

Aktualisiere deine Plattform und folge der Anleitung im Hilfeartikel Code-Modell verwenden, um die Anfrage zu validieren und ein Zugriffs- und Aktualisierungstoken zu erhalten.

Aktualisieren Sie Ihre Plattform, um Funktionen und Funktionen selektiv zu aktivieren oder zu deaktivieren, basierend auf den einzelnen Bereichen, die der Nutzer genehmigt hat. Folgen Sie dazu der Anleitung für die inkrementelle Autorisierung und prüfen Sie die vom Nutzer gewährten Zugriffsbereiche.

Beispiele für implizite Abläufe

Bisherige Methode

GAPI-Clientbibliothek

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

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 im Browser ausgeführt werden und für die Nutzereinwilligung ein Pop-up-Dialogfeld 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 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 wird, leitet den Nutzer zur Einwilligung der Nutzer an Google weiter.

In diesem Beispiel werden direkte Aufrufe der OAuth 2.0-Endpunkte von Google über den Browser des Nutzers dargestellt. Es werden weder das Modul gapi.auth2 noch eine JavaScript-Bibliothek 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 Methode

Nur GIS

In diesem Beispiel wird nur die JavaScript-Bibliothek des Google Identity Service mit dem Tokenmodell und einem Pop-up-Dialogfeld für die Nutzereinwilligung gezeigt. Sie veranschaulicht die Mindestzahl der Schritte, die erforderlich sind, um einen Client zu konfigurieren, ein Zugriffstoken anzufordern und abzurufen und 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 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 Ladereihenfolge der Bibliothek durchzusetzen und Autorisierungsfehler zu erfassen und noch einmal zu versuchen. 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, wenn 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 mit dem Tokenmodell hinzufügen, das gapi.auth2-Modul entfernen und eine API mit der Google API-Clientbibliothek für JavaScript aufrufen.

Mithilfe von Variablen wird die Reihenfolge des Ladens von Bibliotheken erzwungen. GAPI-Aufrufe erfolgen über den Callback, nachdem ein gültiges Zugriffstoken zurückgegeben wurde.

Nutzer müssen die Schaltfläche „Kalender anzeigen“ beim ersten Laden der Seite und noch einmal drücken, 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

Das Pop-up der Google Identity Service-Bibliothek kann entweder eine URL-Weiterleitung verwenden, um einen Autorisierungscode direkt an Ihren Back-End-Tokenendpunkt 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 durch, um ein gültiges Aktualisierungs- und Zugriffstoken zu erhalten.

Bisherige Methode

Serverseitige Web-Apps

Google Log-in für serverseitige Apps, die auf der Backend-Plattform ausgeführt werden und für die Nutzereinwilligung eine Weiterleitung zu Google 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 deine Backend-Plattform zu senden. Die Nutzereinwilligung wird durch Weiterleitung des Browsers des Nutzers an Google verarbeitet.

/\*
 \* 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 Methode

UX für Pop-ups in Google Earth Pro

In diesem Beispiel wird nur die JavaScript-Bibliothek von Google Identity Services gezeigt, in der das Autorisierungscode-Modell verwendet wird. Es enthält ein Pop-up-Dialogfeld für die Nutzereinwilligung und einen Rückruf-Handler, um den Autorisierungscode von Google zu empfangen. Er soll veranschaulichen, wie wenige Schritte erforderlich sind, um einen Client zu konfigurieren, eine Einwilligung einzuholen und einen Autorisierungscode an Ihre Backend-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 die UX-Modi „Pop-up“ und „Weiterleitung“, um einen pro Nutzer gültigen Autorisierungscode an den von Ihrer Plattform gehosteten Endpunkt zu senden. Hier ist der UX-Modus für die Weiterleitung zu sehen:

<!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 aus mehreren verschiedenen Bibliotheken und Modulen:

Aktionen bei der Migration zu Identitätsdiensten:

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 die Bibliothek

Objekt- und Methodenvergleich zwischen der alten Google Sign-In JavaScript-Clientbibliothek und der neuen Google Identity Services-Bibliothek sowie Hinweise mit zusätzlichen Informationen und Maßnahmen, die während der Migration ergriffen werden müssen.

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 Altes durch neue ersetzen. Die Einwilligung kann auch unter https://myaccount.google.com/permissions widerrufen werden.
GoogleAuth.grantOfflineAccess() Entfernen Sie die Karte und folgen Sie dem Autorisierungscode-Vorgang.
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. Die Einwilligung kann auch unter https://myaccount.google.com/permissions widerrufen werden.
GoogleUser.getAuthResponse() requestCode() or requestAccessToken() Altes 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() Altes durch Neues ersetzen
GoogleUser.getHostedDomain() Entfernen
GoogleUser.getId() Entfernen
GoogleUser.grantOfflineAccess() Entfernen Sie den Autorisierungscode und folgen Sie der Anleitung.
GoogleUser.grant() Entfernen
GoogleUser.hasGrantedScopes() hasGrantedAnyScope() Altes durch Neues ersetzen
GoogleUser.isSignedIn() Entfernen
GoogleUser.reloadAuthResponse() requestAccessToken() Entfernen Sie altes oder neues Zugriffstoken, um abgelaufene oder widerrufene Zugriffstokens zu ersetzen.
gapi.auth2 -Objekt und zugehörige Methoden:
Objekt „gapi.auth2.AuthorizeConfig“ TokenClientConfig oder CodeClientConfig Altes durch Neues ersetzen
gapi.auth2.AuthorizeResponse-Objekt Entfernen
gapi.auth2.AuthResponse-Objekt 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
gapi.auth2.OfflineAccessOptions-Objekt Entfernen
gapi.auth2.SignInOptions-Objekt Entfernen
gapi.signin2 -Objekt und zugehörige Methoden:
gapi.signin2.render() Entfernen. Durch das HTML-DOM-Laden des Elements g_id_signin oder den JS-Aufruf an google.accounts.id.renderButton wird der Nutzer in einem Google-Konto angemeldet.

Beispiel für Anmeldedaten

Vorhandene Anmeldedaten

Die Google Sign-In-Plattformbibliothek, die Google API-Clientbibliothek für JavaScript oder direkte Aufrufe von Google Auth 2.0-Endpunkten geben in einer einzigen Antwort sowohl ein OAuth 2.0-Zugriffstoken als auch ein OpenID Connect-ID-Token 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 für die 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 für die Authentifizierung:

    {
      "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

Beispiel für eine Antwort von Google, wenn versucht wird, eine API-Anfrage mit einem abgelaufenen, widerrufenen oder ungültigen Zugriffstoken zu senden:

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"
    }
  }