Tokenmodell verwenden

Mit der google.accounts.oauth2-JavaScript-Bibliothek können Sie Nutzer um ihre Einwilligung bitten und ein Zugriffstoken für die Arbeit mit Nutzerdaten abrufen. Sie basiert auf dem OAuth 2.0-Vorgang Implicit Grant und ermöglicht es Ihnen, Google APIs entweder direkt über REST und CORS aufzurufen oder unsere Google APIs-Clientbibliothek für JavaScript (auch bekannt als gapi.client) für einen einfachen, flexiblen Zugriff auf unsere komplexeren APIs zu verwenden.

Bevor auf geschützte Nutzerdaten über einen Browser zugegriffen werden kann, lösen Nutzer auf Ihrer Website die webbasierten Prozesse von Google zur Kontoauswahl, Anmeldung und Einwilligung aus. Schließlich stellen die OAuth-Server von Google ein Zugriffstoken für Ihre Web-App aus und geben es zurück.

Im tokenbasierten Autorisierungsmodell müssen keine Aktualisierungstokens pro Nutzer auf Ihrem Backend-Server gespeichert werden.

Es wird empfohlen, den hier beschriebenen Ansatz anstelle der Techniken zu verwenden, die im älteren Leitfaden OAuth 2.0 für clientseitige Webanwendungen beschrieben werden.

Vorbereitung

Folgen Sie der Anleitung unter Einrichtung, um den OAuth-Zustimmungsbildschirm zu konfigurieren, eine Client-ID zu erhalten und die Clientbibliothek zu laden.

Token-Client initialisieren

Rufen Sie initTokenClient() auf, um einen neuen Token-Client mit der Client-ID Ihrer Webanwendung zu initialisieren. Sie müssen eine Liste mit einem oder mehreren Bereichen angeben, auf die der Nutzer zugreifen muss:

const client = google.accounts.oauth2.initTokenClient({
  client_id: 'YOUR_GOOGLE_CLIENT_ID',
  scope: 'https://www.googleapis.com/auth/calendar.readonly',
  callback: (response) => {
    ...
  },
});

OAuth 2.0-Token-Flow auslösen

Verwenden Sie die Methode requestAccessToken(), um den UX-Ablauf für das Token auszulösen und ein Zugriffstoken abzurufen. Google fordert den Nutzer auf,

  • Wählen Sie das Konto aus.
  • Melden Sie sich im Google-Konto an, falls Sie das noch nicht getan haben.
  • Sie erteilen die Einwilligung für den Zugriff Ihrer Web-App auf jeden angeforderten Bereich.

Eine Nutzeraktion löst den Token-Ablauf aus: <button onclick="client.requestAccessToken();">Authorize me</button>

Google gibt dann ein TokenResponse mit einem Zugriffstoken und einer Liste der Bereiche zurück, auf die der Nutzer Zugriff gewährt hat, oder einen Fehler an Ihren Callback-Handler.

Nutzer können die Kontoauswahl oder die Anmeldefenster schließen. In diesem Fall wird Ihre Callback-Funktion nicht aufgerufen.

Das Design und die Nutzerfreundlichkeit Ihrer App sollten erst nach einer gründlichen Überprüfung der OAuth 2.0-Richtlinien von Google implementiert werden. Diese Richtlinien umfassen unter anderem die Verwendung mehrerer Bereiche sowie die Erfassung und Verarbeitung der Einwilligung der Nutzer.

Die inkrementelle Autorisierung ist eine Richtlinie und App-Designmethode, mit der der Zugriff auf Ressourcen mithilfe von Bereichen nur bei Bedarf und nicht im Voraus und auf einmal angefordert wird. Nutzer können die Freigabe der einzelnen Ressourcen, die von Ihrer App angefordert werden, genehmigen oder ablehnen. Dies wird als granulare Berechtigungen bezeichnet.

Während dieses Vorgangs fordert Google die Einwilligung des Nutzers an. Dabei wird jeder angeforderte Bereich einzeln aufgeführt. Nutzer wählen die Ressourcen aus, die für Ihre App freigegeben werden sollen. Schließlich ruft Google Ihre Callback-Funktion auf, um ein Zugriffstoken und vom Nutzer genehmigte Bereiche zurückzugeben. Ihre App kann dann die verschiedenen möglichen Ergebnisse, die mit detaillierten Berechtigungen möglich sind, sicher verarbeiten.

Es gibt jedoch Ausnahmen. Google Workspace Enterprise-Apps mit domainweiter Übertragung von Befugnissen oder Apps, die als vertrauenswürdig gekennzeichnet sind, umgehen den Zustimmungsbildschirm für detaillierte Berechtigungen. Für diese Apps wird Nutzern der Bildschirm mit der detaillierten Einwilligung in Berechtigungen nicht angezeigt. Stattdessen erhält Ihre App entweder alle angeforderten Bereiche oder keinen.

Weitere Informationen finden Sie unter Granulare Berechtigungen verwalten.

Inkrementelle Autorisierung

Für Web-Apps werden in den folgenden zwei allgemeinen Szenarien die inkrementelle Autorisierung mit folgenden Methoden veranschaulicht:

  • Eine einseitige Ajax-App, die häufig XMLHttpRequest mit dynamischem Zugriff auf Ressourcen verwendet.
  • Mehrere Webseiten, Ressourcen werden getrennt und seitenweise verwaltet.

Diese beiden Szenarien sollen Designüberlegungen und Methoden veranschaulichen, sind aber nicht als umfassende Empfehlungen für die Einbindung der Einwilligung in Ihre App gedacht. In der Praxis können Apps eine Variation oder Kombination dieser Techniken verwenden.

Ajax

Fügen Sie Ihrer App Unterstützung für die inkrementelle Autorisierung hinzu, indem Sie mehrere Aufrufe an requestAccessToken() vornehmen und den Parameter scope des Objekts OverridableTokenClientConfig verwenden, um einzelne Bereiche bei Bedarf und nur bei Bedarf anzufordern. In diesem Beispiel werden Ressourcen erst angefordert und sind erst sichtbar, nachdem ein Nutzer durch eine Geste einen minimierten Inhaltsbereich maximiert hat.

Ajax-App
Initialisieren Sie den Token-Client beim Laden der Seite:
        const client = google.accounts.oauth2.initTokenClient({
          client_id: 'YOUR_GOOGLE_CLIENT_ID',
          callback: "onTokenResponse",
        });
      
Einwilligung einholen und Zugriffstokens über Nutzeraktionen abrufen: Klicken Sie auf „+“, um Folgendes zu öffnen:

Dokumente zum Lesen

Letzte Dokumente anzeigen

          client.requestAccessToken(
            overrideConfig = ({
               scope = 'https://www.googleapis.com/auth/documents.readonly'
             })
           );
        

Anstehende Veranstaltungen

Kalenderinformationen anzeigen

          client.requestAccessToken(
            overrideConfig = ({
               scope = 'https://www.googleapis.com/auth/calendar.readonly'
             })
           );
        

Fotos anzeigen

          client.requestAccessToken(
            overrideConfig = ({
               scope = 'https://www.googleapis.com/auth/photoslibrary.readonly'
             })
           );
        

Jeder Aufruf von requestAccessToken löst eine Einwilligung des Nutzers aus. Ihre App hat nur Zugriff auf die Ressourcen, die für den Abschnitt erforderlich sind, den ein Nutzer auswählt. So wird die gemeinsame Nutzung von Ressourcen durch die Auswahl des Nutzers eingeschränkt.

Mehrere Webseiten

Beim Design für die inkrementelle Autorisierung werden mehrere Seiten verwendet, um nur die Bereiche anzufordern, die zum Laden einer Seite erforderlich sind. Dadurch wird die Komplexität reduziert und es sind weniger Aufrufe erforderlich, um die Einwilligung des Nutzers einzuholen und ein Zugriffstoken abzurufen.

App mit mehreren Seiten
Webseite Code
Seite 1. Zu lesende Dokumente
  const client = google.accounts.oauth2.initTokenClient({
    client_id: 'YOUR_GOOGLE_CLIENT_ID',
    callback: "onTokenResponse",
    scope: 'https://www.googleapis.com/auth/documents.readonly',
  });
  client.requestAccessToken();
          
Seite 2. Anstehende Veranstaltungen
  const client = google.accounts.oauth2.initTokenClient({
    client_id: 'YOUR_GOOGLE_CLIENT_ID',
    callback: "onTokenResponse",
    scope: 'https://www.googleapis.com/auth/calendar.readonly',
  });
  client.requestAccessToken();
          
Seite 3: Fotokarussell
  const client = google.accounts.oauth2.initTokenClient({
    client_id: 'YOUR_GOOGLE_CLIENT_ID',
    callback: "onTokenResponse",
    scope: 'https://www.googleapis.com/auth/photoslibrary.readonly',
  });
  client.requestAccessToken();
          

Auf jeder Seite wird der erforderliche Bereich angefordert und ein Zugriffstoken durch Aufrufen von initTokenClient() und requestAccessToken() beim Laden abgerufen. In diesem Szenario werden einzelne Webseiten verwendet, um Nutzerfunktionen und Ressourcen nach Umfang klar zu trennen. In der Praxis können einzelne Seiten mehrere zugehörige Bereiche anfordern.

Detaillierte Berechtigungen

Granulare Berechtigungen werden in allen Szenarien auf dieselbe Weise behandelt. Nachdem requestAccessToken() Ihre Callback-Funktion aufgerufen und ein Zugriffstoken zurückgegeben wurde, prüfen Sie mit hasGrantedAllScopes() oder hasGrantedAnyScope(), ob der Nutzer die angeforderten Bereiche genehmigt hat. Beispiel:

const client = google.accounts.oauth2.initTokenClient({
  client_id: 'YOUR_GOOGLE_CLIENT_ID',
  scope: 'https://www.googleapis.com/auth/calendar.readonly \
          https://www.googleapis.com/auth/documents.readonly \
          https://www.googleapis.com/auth/photoslibrary.readonly',
  callback: (tokenResponse) => {
    if (tokenResponse && tokenResponse.access_token) {
      if (google.accounts.oauth2.hasGrantedAnyScope(tokenResponse,
          'https://www.googleapis.com/auth/photoslibrary.readonly')) {
        // Look at pictures
        ...
      }
      if (google.accounts.oauth2.hasGrantedAllScopes(tokenResponse,
          'https://www.googleapis.com/auth/calendar.readonly',
          'https://www.googleapis.com/auth/documents.readonly')) {
        // Meeting planning and review documents
        ...
      }
    }
  },
});

Alle zuvor akzeptierten Berechtigungen aus früheren Sitzungen oder Anfragen werden ebenfalls in die Antwort aufgenommen. Eine Aufzeichnung der Nutzereinwilligung wird pro Nutzer und Client-ID geführt und bleibt über mehrere Aufrufe von initTokenClient() oder requestAccessToken() hinweg bestehen. Standardmäßig ist die Einwilligung des Nutzers nur beim ersten Besuch Ihrer Website und bei der Anfrage eines neuen Bereichs erforderlich. Sie kann jedoch bei jedem Seitenaufbau mit prompt=consent in Token Client-Konfigurationsobjekten angefordert werden.

Mit Tokens arbeiten

Im Token-Modell wird kein Zugriffstoken vom Betriebssystem oder Browser gespeichert. Stattdessen wird beim Laden der Seite oder später durch Auslösen eines Aufrufs von requestAccessToken() über eine Nutzeraktion wie das Drücken einer Schaltfläche ein neues Token abgerufen.

REST und CORS mit Google-APIs verwenden

Mit einem Zugriffstoken können authentifizierte Anfragen an Google APIs über REST und CORS gesendet werden. So können sich Nutzer anmelden, ihre Einwilligung erteilen und Google ein Zugriffstoken ausstellen lassen, damit Ihre Website mit den Daten des Nutzers arbeiten kann.

In diesem Beispiel werden die anstehenden Kalendertermine des angemeldeten Nutzers mit dem von tokenRequest() zurückgegebenen Zugriffstoken aufgerufen:

var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://www.googleapis.com/calendar/v3/calendars/primary/events');
xhr.setRequestHeader('Authorization', 'Bearer ' + tokenResponse.access_token);
xhr.send();

Weitere Informationen finden Sie unter CORS für den Zugriff auf Google APIs verwenden.

Im nächsten Abschnitt wird beschrieben, wie Sie komplexere APIs ganz einfach einbinden können.

Mit der Google APIs JavaScript-Bibliothek arbeiten

Der Token-Client funktioniert mit der Google API-Clientbibliothek für JavaScript. Siehe das Code-Snippet unten.

const client = google.accounts.oauth2.initTokenClient({
  client_id: 'YOUR_GOOGLE_CLIENT_ID',
  scope: 'https://www.googleapis.com/auth/calendar.readonly',
  callback: (tokenResponse) => {
    if (tokenResponse && tokenResponse.access_token) {
      gapi.client.setApiKey('YOUR_API_KEY');
      gapi.client.load('calendar', 'v3', listUpcomingEvents);
    }
  },
});

function listUpcomingEvents() {
  gapi.client.calendar.events.list(...);
}

Ablauf des Tokens

Zugriffstokens haben von Natur aus eine kurze Lebensdauer. Wenn das Zugriffstoken vor dem Ende der Sitzung des Nutzers abläuft, rufen Sie ein neues Token ab, indem Sie requestAccessToken() über ein nutzergesteuertes Ereignis wie einen Tastendruck aufrufen.

Rufen Sie die Methode google.accounts.oauth2.revoke auf, um die Einwilligung des Nutzers und den Zugriff auf Ressourcen für alle Berechtigungsbereiche zu entfernen, die Ihrer App gewährt wurden. Zum Widerrufen dieser Berechtigung ist ein gültiges Zugriffstoken erforderlich:

google.accounts.oauth2.revoke('414a76cb127a7ece7ee4bf287602ca2b56f8fcbf7fcecc2cd4e0509268120bd7', done => {
    console.log(done);
    console.log(done.successful);
    console.log(done.error);
    console.log(done.error_description);
  });