In diesem Dokument wird erläutert, wie Webserveranwendungen Google API-Clientbibliotheken oder Google OAuth 2.0-Endpunkte verwenden, um die OAuth 2.0-Autorisierung für den Zugriff auf Google APIs zu implementieren.
OAuth 2.0 ermöglicht Nutzern, bestimmte Daten für eine Anwendung freizugeben, während ihre Nutzernamen, Passwörter und andere Informationen privat bleiben. Eine Anwendung kann beispielsweise OAuth 2.0 verwenden, um von Nutzern die Berechtigung zum Speichern von Dateien in Google Drive zu erhalten.
Dieser OAuth 2.0-Vorgang ist speziell für die Nutzerautorisierung vorgesehen. Er ist für Anwendungen konzipiert, die vertrauliche Informationen speichern und den Status beibehalten können. Eine ordnungsgemäß autorisierte Webserveranwendung kann auf eine API zugreifen, während der Nutzer mit der Anwendung interagiert oder nachdem er die Anwendung verlassen hat.
Webserveranwendungen verwenden häufig auch Dienstkonten, um API-Anfragen zu autorisieren, insbesondere wenn Cloud APIs aufgerufen werden, um auf projektbasierte Daten und nicht auf nutzerspezifische Daten zuzugreifen. Webserveranwendungen können Dienstkonten in Verbindung mit der Nutzerautorisierung verwenden.
Clientbibliotheken
In den sprachspezifischen Beispielen auf dieser Seite werden die Google API-Clientbibliotheken verwendet, um die OAuth 2.0-Autorisierung zu implementieren. Zum Ausführen der Codebeispiele müssen Sie zuerst die Clientbibliothek für Ihre Sprache installieren.
Wenn Sie eine Google API-Clientbibliothek verwenden, um den OAuth 2.0-Vorgang Ihrer Anwendung zu verarbeiten, führt die Clientbibliothek viele Aktionen aus, die die Anwendung sonst selbst verarbeiten müsste. Sie bestimmt beispielsweise, wann die Anwendung gespeicherte Zugriffstokens verwenden oder aktualisieren kann und wann die Anwendung die Einwilligung noch einmal einholen muss. Die Clientbibliothek generiert auch korrekte Weiterleitungs-URLs und hilft bei der Implementierung von Weiterleitungs-Handlern, die Autorisierungscodes gegen Zugriffstokens austauschen.
Google API-Clientbibliotheken für serverseitige Anwendungen sind für die folgenden Sprachen verfügbar:
Vorbereitung
Die APIs für Ihr Projekt aktivieren
Für jede Anwendung, die Google APIs aufruft, müssen diese APIs in der API Console aktiviert werden.
So aktivieren Sie eine API für Ihr Projekt:
- Öffnen Sie die API-Bibliothek in der Google API Console.
- Wählen Sie ein Projekt aus oder erstellen Sie ein neues, wenn Sie dazu aufgefordert werden.
- In der API-Bibliothek finden Sie alle verfügbaren APIs, gruppiert nach Produktfamilie und Beliebtheit. Wenn die API, die Sie aktivieren möchten, nicht in der Liste angezeigt wird, können Sie die Suchfunktion verwenden oder in der Produktfamilie, zu der sie gehört, auf Alle ansehen klicken.
- Wählen Sie die gewünschte API aus und klicken Sie dann auf den Button Aktivieren.
- Aktivieren Sie die Abrechnung, wenn Sie dazu aufgefordert werden.
- Lesen und akzeptieren Sie die Nutzungsbedingungen der API, wenn Sie dazu aufgefordert werden.
Anmeldedaten für die Autorisierung erstellen
Jede Anwendung, die OAuth 2.0 für den Zugriff auf Google APIs verwendet, muss über Autorisierungsdaten verfügen, mit denen sie sich gegenüber dem OAuth 2.0-Server von Google identifiziert. In den folgenden Schritten wird beschrieben, wie Sie Anmeldedaten für Ihr Projekt erstellen. Ihre Anwendungen können dann mit den Anmeldedaten auf APIs zugreifen, die Sie für dieses Projekt aktiviert haben.
- Rufen Sie die Seite „Clients“ auf.
- Klicken Sie auf Client erstellen.
- Wählen Sie den Anwendungstyp Webanwendung aus.
- Füllen Sie das Formular aus und klicken Sie auf Erstellen. Für Anwendungen, die Sprachen und Frameworks wie PHP, Java, Python, Ruby und .NET verwenden, müssen autorisierte Weiterleitungs-URIs angegeben werden. Die Weiterleitungs-URIs sind die Endpunkte, an die der OAuth 2.0-Server Antworten senden kann. Diese Endpunkte müssen den Validierungsregeln von Google entsprechen.
Zu Testzwecken können Sie URIs angeben, die sich auf den lokalen Computer beziehen, z. B.
http://localhost:8080. In allen Beispielen in diesem Dokument wirdhttp://localhost:8080als Weiterleitungs-URI verwendet.Wir empfehlen, die Authentifizierungsendpunkte Ihrer App so zu gestalten, dass Ihre Anwendung keine Autorisierungscodes für andere Ressourcen auf der Seite preisgibt.
Laden Sie nach dem Erstellen der Anmeldedaten die Datei client_secret.json aus der API Console herunter. Speichern Sie die Datei an einem sicheren Ort, auf den nur Ihre Anwendung zugreifen kann.
Zugriffsbereiche identifizieren
Mit Bereichen kann Ihre Anwendung nur Zugriff auf die Ressourcen anfordern, die sie benötigt. Außerdem können Nutzer so den Umfang des Zugriffs steuern, den sie Ihrer Anwendung gewähren. Es kann also eine umgekehrte Beziehung zwischen der Anzahl der angeforderten Bereiche und der Wahrscheinlichkeit geben, dass die Nutzereinwilligung erteilt wird.
Bevor Sie mit der Implementierung der OAuth 2.0-Autorisierung beginnen, sollten Sie die Bereiche ermitteln, für die Ihre App Zugriffsberechtigungen benötigt.
Wir empfehlen außerdem, dass Ihre Anwendung den Zugriff auf Autorisierungsbereiche über einen inkrementellen Autorisierungsprozess anfordert, bei dem Ihre Anwendung den Zugriff auf Nutzerdaten im Kontext anfordert. Diese Best Practice hilft Nutzern, besser zu verstehen, warum Ihre Anwendung den angeforderten Zugriff benötigt.
Das Dokument OAuth 2.0-API-Bereiche enthält eine vollständige Liste der Bereiche, die Sie für den Zugriff auf Google APIs verwenden können.
Sprachspezifische Anforderungen
Wenn Sie die Codebeispiele in diesem Dokument ausführen möchten, benötigen Sie ein Google-Konto, Internetzugriff und einen Webbrowser. Wenn Sie eine der API-Clientbibliotheken verwenden, beachten Sie auch die sprachspezifischen Anforderungen in den folgenden Abschnitten.
PHP
Wenn Sie die PHP-Codebeispiele in diesem Dokument ausführen möchten, benötigen Sie Folgendes:
- PHP 8.0 oder höher mit installierter Befehlszeile (CLI) und JSON-Erweiterung.
- Das Tool Composer für die Abhängigkeitsverwaltung.
-
Die Google APIs-Clientbibliothek für PHP:
composer require google/apiclient:^2.15.0
Weitere Informationen finden Sie unter Google APIs-Clientbibliothek für PHP.
Python
Wenn Sie die Python-Codebeispiele in diesem Dokument ausführen möchten, benötigen Sie Folgendes:
- Python 3.7 oder höher
- Das Paketverwaltungstool pip.
- Die Google API-Clientbibliothek für Python 2.0:
pip install --upgrade google-api-python-client
google-auth,google-auth-oauthlibundgoogle-auth-httplib2für die Nutzerautorisierung.pip install --upgrade google-auth google-auth-oauthlib google-auth-httplib2
- Das Flask-Python-Webanwendungs-Framework.
pip install --upgrade flask
- Die HTTP-Bibliothek
requests.pip install --upgrade requests
Lesen Sie die Versionshinweise zur Google API-Python-Clientbibliothek, wenn Sie Python nicht aktualisieren können, und die zugehörige Migrationsanleitung.
Ruby
Wenn Sie die Ruby-Codebeispiele in diesem Dokument ausführen möchten, benötigen Sie Folgendes:
- Ruby 2.6 oder höher
-
Die Google Auth-Bibliothek für Ruby:
gem install googleauth
-
Die Clientbibliotheken für die Google APIs für Drive und Kalender:
gem install google-apis-drive_v3 google-apis-calendar_v3
-
Das Sinatra-Ruby-Webanwendungs-Framework.
gem install sinatra
Node.js
Wenn Sie die Node.js-Codebeispiele in diesem Dokument ausführen möchten, benötigen Sie Folgendes:
- Der Wartungs-LTS, der aktive LTS oder der aktuelle Release von Node.js.
-
Der Google APIs Node.js-Client:
npm install googleapis crypto express express-session
HTTP/REST
Sie müssen keine Bibliotheken installieren, um die OAuth 2.0-Endpunkte direkt aufrufen zu können.
OAuth 2.0-Zugriffstokens abrufen
In den folgenden Schritten wird gezeigt, wie Ihre Anwendung mit dem OAuth 2.0-Server von Google interagiert, um die Einwilligung eines Nutzers einzuholen, eine API-Anfrage im Namen des Nutzers auszuführen. Ihre Anwendung muss diese Einwilligung einholen, bevor sie eine Google API-Anfrage ausführen kann, für die eine Nutzerautorisierung erforderlich ist.
In der folgenden Liste sind diese Schritte kurz zusammengefasst:
- Ihre Anwendung gibt die erforderlichen Berechtigungen an.
- Ihre Anwendung leitet den Nutzer zusammen mit der Liste der angeforderten Berechtigungen an Google weiter.
- Der Nutzer entscheidet, ob er Ihrer Anwendung die Berechtigungen gewährt.
- Ihre Anwendung erfährt, was der Nutzer entschieden hat.
- Wenn der Nutzer die angeforderten Berechtigungen gewährt hat, ruft Ihre Anwendung die Tokens ab, die für API-Anfragen im Namen des Nutzers erforderlich sind.
Schritt 1: Autorisierungsparameter festlegen
Der erste Schritt besteht darin, die Autorisierungsanfrage zu erstellen. In dieser Anfrage werden Parameter festgelegt, die Ihre Anwendung identifizieren und die Berechtigungen definieren, die der Nutzer Ihrer Anwendung gewähren soll.
- Wenn Sie eine Google-Clientbibliothek für die OAuth 2.0-Authentifizierung und -Autorisierung verwenden, erstellen und konfigurieren Sie ein Objekt, das diese Parameter definiert.
- Wenn Sie den Google OAuth 2.0-Endpunkt direkt aufrufen, generieren Sie eine URL und legen die Parameter für diese URL fest.
Auf den folgenden Tabs werden die unterstützten Autorisierungsparameter für Webserveranwendungen definiert. In den sprachspezifischen Beispielen wird auch gezeigt, wie Sie mit einer Clientbibliothek oder Autorisierungsbibliothek ein Objekt konfigurieren, das diese Parameter festlegt:
PHP
Mit dem folgenden Code-Snippet wird ein Google\Client()-Objekt erstellt, das die Parameter in der Autorisierungsanfrage definiert.
Dieses Objekt verwendet Informationen aus der Datei client_secret.json, um Ihre Anwendung zu identifizieren. Weitere Informationen zu dieser Datei finden Sie unter Anmeldedaten für die Autorisierung erstellen. Das Objekt identifiziert auch die Bereiche, für die Ihre Anwendung eine Zugriffsberechtigung anfordert, und die URL zum Autorisierungsendpunkt Ihrer Anwendung, der die Antwort vom OAuth 2.0-Server von Google verarbeitet. Schließlich werden im Code die optionalen Parameter access_type und include_granted_scopes festgelegt.
Mit diesem Code wird beispielsweise der schreibgeschützte Offlinezugriff auf die Google Drive-Metadaten und Google Kalender-Termine eines Nutzers angefordert:
use Google\Client; $client = new Client(); // Required, call the setAuthConfig function to load authorization credentials from // client_secret.json file. $client->setAuthConfig('client_secret.json'); // Required, to set the scope value, call the addScope function $client->addScope([Google\Service\Drive::DRIVE_METADATA_READONLY, Google\Service\Calendar::CALENDAR_READONLY]); // Required, call the setRedirectUri function to specify a valid redirect URI for the // provided client_id $client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php'); // Recommended, offline access will give you both an access and refresh token so that // your app can refresh the access token without user interaction. $client->setAccessType('offline'); // Recommended, call the setState function. Using a state value can increase your assurance that // an incoming connection is the result of an authentication request. $client->setState($sample_passthrough_value); // Optional, if your application knows which user is trying to authenticate, it can use this // parameter to provide a hint to the Google Authentication Server. $client->setLoginHint('hint@example.com'); // Optional, call the setPrompt function to set "consent" will prompt the user for consent $client->setPrompt('consent'); // Optional, call the setIncludeGrantedScopes function with true to enable incremental // authorization $client->setIncludeGrantedScopes(true);
Python
Im folgenden Code-Snippet wird das Modul google-auth-oauthlib.flow verwendet, um die Autorisierungsanfrage zu erstellen.
Der Code erstellt ein Flow-Objekt, das Ihre Anwendung anhand von Informationen aus der Datei client_secret.json identifiziert, die Sie nach dem Erstellen von Autorisierungsanmeldedaten heruntergeladen haben. Dieses Objekt identifiziert auch die Bereiche, für die Ihre Anwendung eine Zugriffsberechtigung anfordert, und die URL zum Autorisierungsendpunkt Ihrer Anwendung, der die Antwort vom OAuth 2.0-Server von Google verarbeitet. Schließlich werden im Code die optionalen Parameter access_type und include_granted_scopes festgelegt.
Mit diesem Code wird beispielsweise der schreibgeschützte Offlinezugriff auf die Google Drive-Metadaten und Google Kalender-Termine eines Nutzers angefordert:
import google.oauth2.credentials import google_auth_oauthlib.flow # Required, call the from_client_secrets_file method to retrieve the client ID from a # client_secret.json file. The client ID (from that file) and access scopes are required. (You can # also use the from_client_config method, which passes the client configuration as it originally # appeared in a client secrets file but doesn't access the file itself.) flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file('client_secret.json', scopes=['https://www.googleapis.com/auth/drive.metadata.readonly', 'https://www.googleapis.com/auth/calendar.readonly']) # Required, indicate where the API server will redirect the user after the user completes # the authorization flow. The redirect URI is required. The value must exactly # match one of the authorized redirect URIs for the OAuth 2.0 client, which you # configured in the API Console. If this value doesn't match an authorized URI, # you will get a 'redirect_uri_mismatch' error. flow.redirect_uri = 'https://www.example.com/oauth2callback' # Generate URL for request to Google's OAuth 2.0 server. # Use kwargs to set optional request parameters. authorization_url, state = flow.authorization_url( # Recommended, enable offline access so that you can refresh an access token without # re-prompting the user for permission. Recommended for web server apps. access_type='offline', # Optional, enable incremental authorization. Recommended as a best practice. include_granted_scopes='true', # Optional, if your application knows which user is trying to authenticate, it can use this # parameter to provide a hint to the Google Authentication Server. login_hint='hint@example.com', # Optional, set prompt to 'consent' will prompt the user for consent prompt='consent')
Ruby
Verwenden Sie die von Ihnen erstellte Datei „client_secrets.json“, um ein Clientobjekt in Ihrer Anwendung zu konfigurieren. Wenn Sie ein Clientobjekt konfigurieren, geben Sie die Bereiche an, auf die Ihre Anwendung zugreifen muss, sowie die URL zum Authentifizierungsendpunkt Ihrer Anwendung, der die Antwort vom OAuth 2.0-Server verarbeitet.
Mit diesem Code wird beispielsweise der Offline-Lesezugriff auf die Google Drive-Metadaten und Google Kalender-Termine eines Nutzers angefordert:
require 'googleauth' require 'googleauth/web_user_authorizer' require 'googleauth/stores/redis_token_store' require 'google/apis/drive_v3' require 'google/apis/calendar_v3' # Required, call the from_file method to retrieve the client ID from a # client_secret.json file. client_id = Google::Auth::ClientId.from_file('/path/to/client_secret.json') # Required, scope value # Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar. scope = ['Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY', 'Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY'] # Required, Authorizers require a storage instance to manage long term persistence of # access and refresh tokens. token_store = Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new) # Required, indicate where the API server will redirect the user after the user completes # the authorization flow. The redirect URI is required. The value must exactly # match one of the authorized redirect URIs for the OAuth 2.0 client, which you # configured in the API Console. If this value doesn't match an authorized URI, # you will get a 'redirect_uri_mismatch' error. callback_uri = '/oauth2callback' # To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI # from the client_secret.json file. To get these credentials for your application, visit # https://console.cloud.google.com/apis/credentials. authorizer = Google::Auth::WebUserAuthorizer.new(client_id, scope, token_store, callback_uri)
Ihre Anwendung verwendet das Clientobjekt, um OAuth 2.0-Vorgänge auszuführen, z. B. das Generieren von URLs für Autorisierungsanfragen und das Anwenden von Zugriffstokens auf HTTP-Anfragen.
Node.js
Mit dem folgenden Code-Snippet wird ein google.auth.OAuth2-Objekt erstellt, das die Parameter in der Autorisierungsanfrage definiert.
Dieses Objekt verwendet Informationen aus Ihrer Datei „client_secret.json“, um Ihre Anwendung zu identifizieren. Wenn Sie einen Nutzer um die Berechtigung zum Abrufen eines Zugriffstokens bitten möchten, leiten Sie ihn auf eine Einwilligungsseite weiter. So erstellen Sie eine URL für die Einwilligungsseite:
const {google} = require('googleapis'); const crypto = require('crypto'); const express = require('express'); const session = require('express-session'); /** * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI * from the client_secret.json file. To get these credentials for your application, visit * https://console.cloud.google.com/apis/credentials. */ const oauth2Client = new google.auth.OAuth2( YOUR_CLIENT_ID, YOUR_CLIENT_SECRET, YOUR_REDIRECT_URL ); // Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar. const scopes = [ 'https://www.googleapis.com/auth/drive.metadata.readonly', 'https://www.googleapis.com/auth/calendar.readonly' ]; // Generate a secure random state value. const state = crypto.randomBytes(32).toString('hex'); // Store state in the session req.session.state = state; // Generate a url that asks permissions for the Drive activity and Google Calendar scope const authorizationUrl = oauth2Client.generateAuthUrl({ // 'online' (default) or 'offline' (gets refresh_token) access_type: 'offline', /** Pass in the scopes array defined above. * Alternatively, if only one scope is needed, you can pass a scope URL as a string */ scope: scopes, // Enable incremental authorization. Recommended as a best practice. include_granted_scopes: true, // Include the state parameter to reduce the risk of CSRF attacks. state: state });
Wichtiger Hinweis: Das refresh_token wird nur bei der ersten Autorisierung zurückgegeben.
Weitere Informationen
HTTP/REST
Der OAuth 2.0-Endpunkt von Google befindet sich unter https://accounts.google.com/o/oauth2/v2/auth. Dieser Endpunkt ist nur über HTTPS zugänglich. Einfache HTTP-Verbindungen werden abgelehnt.
Der Google-Autorisierungsserver unterstützt die folgenden Abfragestringparameter für Webserveranwendungen:
| Parameter | |||||||
|---|---|---|---|---|---|---|---|
client_id |
Erforderlich
Die Client-ID für Ihre Anwendung. Sie finden diesen Wert in der Cloud Console auf der Seite „Clients“. |
||||||
redirect_uri |
Erforderlich
Bestimmt, wohin der API-Server den Nutzer weiterleitet, nachdem er den Autorisierungsablauf abgeschlossen hat. Der Wert muss genau mit einem der autorisierten Weiterleitungs-URIs für den OAuth 2.0-Client übereinstimmen, den Sie in der Cloud Console auf der Seite „Clients“ Ihres Clients konfiguriert haben. Wenn dieser Wert nicht mit einem autorisierten Weiterleitungs-URI für die angegebene Das Schema |
||||||
response_type |
Erforderlich
Bestimmt, ob der Google OAuth 2.0-Endpunkt einen Autorisierungscode zurückgibt. Legen Sie den Parameterwert für Webserveranwendungen auf |
||||||
scope |
Erforderlich
Eine durch Leerzeichen getrennte Liste von Bereichen, die die Ressourcen identifizieren, auf die Ihre Anwendung im Namen des Nutzers zugreifen kann. Diese Werte werden auf dem Zustimmungsbildschirm angezeigt, den Google dem Nutzer präsentiert. Mit Bereichen kann Ihre Anwendung nur Zugriff auf die Ressourcen anfordern, die sie benötigt. Außerdem können Nutzer so den Umfang des Zugriffs steuern, den sie Ihrer Anwendung gewähren. Es besteht also eine umgekehrte Beziehung zwischen der Anzahl der angeforderten Bereiche und der Wahrscheinlichkeit, dass die Nutzereinwilligung erteilt wird. Wir empfehlen, dass Ihre Anwendung nach Möglichkeit im Kontext Zugriff auf Autorisierungsbereiche anfordert. Wenn Sie den Zugriff auf Nutzerdaten im Kontext über die inkrementelle Autorisierung anfordern, können Nutzer besser nachvollziehen, warum Ihre Anwendung den angeforderten Zugriff benötigt. |
||||||
access_type |
Empfohlen
Gibt an, ob Ihre Anwendung Zugriffstokens aktualisieren kann, wenn der Nutzer nicht im Browser angemeldet ist. Gültige Parameterwerte sind Legen Sie den Wert auf |
||||||
state |
Empfohlen
Gibt einen beliebigen Stringwert an, den Ihre Anwendung verwendet, um den Status zwischen Ihrer Autorisierungsanfrage und der Antwort des Autorisierungsservers beizubehalten.
Der Server gibt den genauen Wert zurück, den Sie als Sie können diesen Parameter für verschiedene Zwecke verwenden, z. B. um den Nutzer zur richtigen Ressource in Ihrer Anwendung weiterzuleiten, Nonces zu senden und websiteübergreifende Anfragen zu verhindern. Da Ihre |
||||||
include_granted_scopes |
Optional
Ermöglicht Anwendungen, die inkrementelle Autorisierung zu verwenden, um Zugriff auf zusätzliche Bereiche im Kontext anzufordern. Wenn Sie den Wert dieses Parameters auf |
||||||
enable_granular_consent |
Optional
Die Standardeinstellung ist Wenn Google detaillierte Berechtigungen für eine Anwendung aktiviert, hat dieser Parameter keine Auswirkungen mehr. |
||||||
login_hint |
Optional
Wenn Ihre Anwendung weiß, welcher Nutzer versucht, sich zu authentifizieren, kann sie diesen Parameter verwenden, um dem Google-Authentifizierungsserver einen Hinweis zu geben. Der Server verwendet den Hinweis, um den Anmeldevorgang zu vereinfachen, indem er entweder das E-Mail-Feld im Anmeldeformular vorausfüllt oder die entsprechende Multi-Login-Sitzung auswählt. Legen Sie den Parameterwert auf eine E-Mail-Adresse oder eine |
||||||
prompt |
Optional
Eine durch Leerzeichen getrennte Liste von Aufforderungen, die dem Nutzer angezeigt werden sollen. Bei der Liste wird zwischen Groß- und Kleinschreibung unterschieden. Wenn Sie diesen Parameter nicht angeben, wird der Nutzer nur beim ersten Mal aufgefordert, wenn Ihr Projekt Zugriff anfordert. Weitere Informationen finden Sie unter Erneute Einwilligung einholen. Folgende Werte sind möglich:
|
||||||
Schritt 2: Weiterleitung zum OAuth 2.0-Server von Google
Leiten Sie den Nutzer zum OAuth 2.0-Server von Google weiter, um den Authentifizierungs- und Autorisierungsprozess zu starten. In der Regel geschieht dies, wenn Ihre Anwendung zum ersten Mal auf die Daten des Nutzers zugreifen muss. Bei der inkrementellen Autorisierung erfolgt dieser Schritt auch, wenn Ihre Anwendung zum ersten Mal auf zusätzliche Ressourcen zugreifen muss, für die sie keine Zugriffsberechtigung hat.
PHP
- Generieren Sie eine URL, um Zugriff vom OAuth 2.0-Server von Google anzufordern:
$auth_url = $client->createAuthUrl(); - Leiten Sie den Nutzer zu
$auth_urlweiter:header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
Python
In diesem Beispiel wird gezeigt, wie der Nutzer mithilfe des Flask-Webanwendungs-Frameworks zur Autorisierungs-URL weitergeleitet wird:
return flask.redirect(authorization_url)
Ruby
- Generieren Sie eine URL, um Zugriff vom OAuth 2.0-Server von Google anzufordern:
auth_uri = authorizer.get_authorization_url(request: request)
- Leiten Sie den Nutzer an
auth_uriweiter.
Node.js
-
Verwenden Sie die generierte URL
authorizationUrlaus Schritt 1, um mit der MethodegenerateAuthUrlZugriff vom OAuth 2.0-Server von Google anzufordern. -
Leiten Sie den Nutzer an
authorizationUrlweiter.res.redirect(authorizationUrl);
HTTP/REST
Beispiel für eine Weiterleitung zum Autorisierungsserver von Google
Unten sehen Sie eine Beispiel-URL mit Zeilenumbrüchen und Leerzeichen zur besseren Lesbarkeit.
https://accounts.google.com/o/oauth2/v2/auth? scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly%20https%3A//www.googleapis.com/auth/calendar.readonly& access_type=offline& include_granted_scopes=true& response_type=code& state=state_parameter_passthrough_value& redirect_uri=https%3A//developers.google.com/oauthplayground& client_id=client_id
Nachdem Sie die Anfrage-URL erstellt haben, leiten Sie den Nutzer dorthin weiter.
Der OAuth 2.0-Server von Google authentifiziert den Nutzer und holt seine Zustimmung ein, damit Ihre Anwendung auf die angeforderten Bereiche zugreifen kann. Die Antwort wird über die von Ihnen angegebene Weiterleitungs-URL an Ihre Anwendung zurückgesendet.
Schritt 3: Google fordert den Nutzer auf, seine Einwilligung zu erteilen
In diesem Schritt entscheidet der Nutzer, ob er Ihrer Anwendung den angeforderten Zugriff gewährt. In dieser Phase zeigt Google ein Zustimmungsfenster an, in dem der Name Ihrer Anwendung und die Google API-Dienste, für die sie mit den Autorisierungsdaten des Nutzers Zugriff anfordert, sowie eine Zusammenfassung der zu gewährenden Zugriffsbereiche aufgeführt sind. Der Nutzer kann dann zustimmen, den Zugriff auf einen oder mehrere von Ihrer Anwendung angeforderte Bereiche zu gewähren, oder die Anfrage ablehnen.
Ihre Anwendung muss in dieser Phase nichts tun, während sie auf die Antwort des OAuth 2.0-Servers von Google wartet, die angibt, ob Zugriff gewährt wurde. Diese Antwort wird im folgenden Schritt erläutert.
Fehler
Bei Anfragen an den OAuth 2.0-Autorisierungsendpunkt von Google werden möglicherweise Fehlermeldungen für Nutzer angezeigt, anstatt der erwarteten Authentifizierungs- und Autorisierungsabläufe. Häufige Fehlercodes und Lösungsvorschläge:
admin_policy_enforced
Das Google-Konto kann aufgrund der Richtlinien des Google Workspace-Administrators einen oder mehrere angeforderte Bereiche nicht autorisieren. Weitere Informationen dazu, wie ein Administrator den Zugriff auf alle Bereiche oder auf sensible und eingeschränkte Bereiche einschränken kann, bis der Zugriff explizit für Ihre OAuth-Client-ID gewährt wird, finden Sie im Hilfeartikel für Google Workspace-Administratoren Festlegen, welche Apps auf Google Workspace-Daten zugreifen können.
disallowed_useragent
Der Autorisierungsendpunkt wird in einem eingebetteten User-Agent angezeigt, der gemäß den OAuth 2.0-Richtlinien von Google nicht zulässig ist.
iOS- und macOS-Entwickler können diesen Fehler beim Öffnen von Autorisierungsanfragen in WKWebView erhalten.
Entwickler sollten stattdessen iOS-Bibliotheken wie Google Log-in für iOS oder AppAuth für iOS der OpenID Foundation verwenden.
Webentwickler können auf diesen Fehler stoßen, wenn eine iOS- oder macOS-App einen allgemeinen Weblink in einem eingebetteten User-Agent öffnet und ein Nutzer von Ihrer Website zum OAuth 2.0-Autorisierungsendpunkt von Google navigiert. Entwickler sollten zulassen, dass allgemeine Links im Standard-Link-Handler des Betriebssystems geöffnet werden. Dazu gehören sowohl Universal Links-Handler als auch die Standardbrowser-App. Die SFSafariViewController-Bibliothek ist ebenfalls eine unterstützte Option.
org_internal
Die OAuth-Client-ID in der Anfrage ist Teil eines Projekts, das den Zugriff auf Google-Konten in einer bestimmten Google Cloud-Organisation einschränkt. Weitere Informationen zu dieser Konfigurationsoption finden Sie im Hilfeartikel „OAuth-Zustimmungsbildschirm einrichten“ im Abschnitt Nutzertyp.
invalid_client
Der OAuth-Clientschlüssel ist falsch. Prüfen Sie die OAuth-Clientkonfiguration, einschließlich der Client-ID und des Secrets, die für diese Anfrage verwendet wurden.
deleted_client
Der OAuth-Client, der zum Senden der Anfrage verwendet wird, wurde gelöscht. Das Löschen kann manuell oder im Fall von nicht verwendeten Clients automatisch erfolgen. Gelöschte Clients können innerhalb von 30 Tagen nach dem Löschen wiederhergestellt werden. Weitere Informationen
invalid_grant
Beim Aktualisieren eines Zugriffstokens oder bei der Verwendung der inkrementellen Autorisierung ist das Token möglicherweise abgelaufen oder wurde ungültig gemacht. Authentifizieren Sie den Nutzer noch einmal und bitten Sie ihn um seine Einwilligung, um neue Tokens zu erhalten. Wenn dieser Fehler weiterhin auftritt, prüfen Sie, ob Ihre Anwendung richtig konfiguriert ist und ob Sie die richtigen Tokens und Parameter in Ihrer Anfrage verwenden. Andernfalls wurde das Nutzerkonto möglicherweise gelöscht oder deaktiviert.
redirect_uri_mismatch
Der in der Autorisierungsanfrage übergebene redirect_uri stimmt nicht mit einem autorisierten Weiterleitungs-URI für die OAuth-Client-ID überein. Prüfen Sie die autorisierten Weiterleitungs-URIs auf der Seite „Clients“ in der Google Cloud Console.
Der Parameter redirect_uri bezieht sich möglicherweise auf den OAuth-Out-of-Band-Ablauf (OOB), der eingestellt wurde und nicht mehr unterstützt wird. Informationen zum Aktualisieren Ihrer Integration finden Sie in der Migrationsanleitung.
invalid_request
Bei Ihrer Anfrage ist ein Fehler aufgetreten. Das kann verschiedene Gründe haben:
- Die Anfrage war nicht richtig formatiert.
- In der Anfrage fehlten erforderliche Parameter.
- Für die Anfrage wird eine Autorisierungsmethode verwendet, die von Google nicht unterstützt wird. Prüfen, ob für Ihre OAuth-Integration eine empfohlene Integrationsmethode verwendet wird
Schritt 4: OAuth 2.0-Serverantwort verarbeiten
Der OAuth 2.0-Server antwortet auf die Zugriffsanfrage Ihrer Anwendung über die in der Anfrage angegebene URL.
Wenn der Nutzer die Zugriffsanfrage genehmigt, enthält die Antwort einen Autorisierungscode. Wenn der Nutzer die Anfrage nicht genehmigt, enthält die Antwort eine Fehlermeldung. Der Autorisierungscode oder die Fehlermeldung, die an den Webserver zurückgegeben wird, wird im Abfragestring angezeigt, wie in den folgenden Beispielen gezeigt:
Eine Fehlerantwort:
https://oauth2.example.com/auth?error=access_denied
Eine Autorisierungscode-Antwort:
https://oauth2.example.com/auth?code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7
Beispiel für eine OAuth 2.0-Serverantwort
Sie können diesen Ablauf testen, indem Sie auf die folgende Beispiel-URL klicken, die Lesezugriff auf Metadaten für Dateien in Ihrem Google Drive und Lesezugriff auf Ihre Google Kalender-Termine anfordert:
https://accounts.google.com/o/oauth2/v2/auth? scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly%20https%3A//www.googleapis.com/auth/calendar.readonly& access_type=offline& include_granted_scopes=true& response_type=code& state=state_parameter_passthrough_value& redirect_uri=https%3A//developers.google.com/oauthplayground& client_id=client_id
Nach Abschluss des OAuth 2.0-Vorgangs werden Sie im Browser zum OAuth 2.0 Playground weitergeleitet, einem Tool zum Testen von OAuth-Vorgängen. Sie sehen, dass der OAuth 2.0 Playground den Autorisierungscode automatisch erfasst hat.
Schritt 5: Autorisierungscode gegen Aktualisierungs- und Zugriffstokens austauschen
Nachdem der Webserver den Autorisierungscode erhalten hat, kann er ihn gegen ein Zugriffstoken eintauschen.
PHP
Verwenden Sie die Methode fetchAccessTokenWithAuthCode, um einen Autorisierungscode gegen ein Zugriffstoken auszutauschen:
$access_token = $client->fetchAccessTokenWithAuthCode($_GET['code']);Python
Verwende auf deiner Callback-Seite die google-auth-Bibliothek, um die Antwort des Autorisierungsservers zu prüfen. Verwenden Sie dann die Methode flow.fetch_token, um den Autorisierungscode in dieser Antwort gegen ein Zugriffstoken auszutauschen:
state = flask.session['state'] flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file( 'client_secret.json', scopes=['https://www.googleapis.com/auth/drive.metadata.readonly'], state=state) flow.redirect_uri = flask.url_for('oauth2callback', _external=True) authorization_response = flask.request.url flow.fetch_token(authorization_response=authorization_response) # Store the credentials in browser session storage, but for security: client_id, client_secret, # and token_uri are instead stored only on the backend server. credentials = flow.credentials flask.session['credentials'] = { 'token': credentials.token, 'refresh_token': credentials.refresh_token, 'granted_scopes': credentials.granted_scopes}
Ruby
Verwende auf deiner Callback-Seite die googleauth-Bibliothek, um die Antwort des Autorisierungsservers zu prüfen. Verwenden Sie die Methode authorizer.handle_auth_callback_deferred, um den Autorisierungscode zu speichern und zur URL zurückzuleiten, die ursprünglich die Autorisierung angefordert hat. Dadurch wird der Austausch des Codes verzögert, indem die Ergebnisse vorübergehend in der Sitzung des Nutzers gespeichert werden.
target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request) redirect target_url
Node.js
Verwenden Sie die Methode getToken, um einen Autorisierungscode gegen ein Zugriffstoken auszutauschen:
const url = require('url'); // Receive the callback from Google's OAuth 2.0 server. app.get('/oauth2callback', async (req, res) => { let q = url.parse(req.url, true).query; if (q.error) { // An error response e.g. error=access_denied console.log('Error:' + q.error); } else if (q.state !== req.session.state) { //check state value console.log('State mismatch. Possible CSRF attack'); res.end('State mismatch. Possible CSRF attack'); } else { // Get access and refresh tokens (if access_type is offline) let { tokens } = await oauth2Client.getToken(q.code); oauth2Client.setCredentials(tokens); });
HTTP/REST
Wenn Sie einen Autorisierungscode gegen ein Zugriffstoken eintauschen möchten, rufen Sie den Endpunkt https://oauth2.googleapis.com/token auf und legen Sie die folgenden Parameter fest:
| Felder | |
|---|---|
client_id |
Die Client-ID, die Sie auf der Seite „Clients“ in der Cloud Console erhalten haben. |
client_secret |
Optional
Der Clientschlüssel, der auf der Seite „Clients“ der Cloud Console abgerufen wurde. |
code |
Der Autorisierungscode, der von der ersten Anfrage zurückgegeben wurde. |
grant_type |
Wie in der OAuth 2.0-Spezifikation definiert, muss der Wert dieses Felds auf authorization_code festgelegt werden. |
redirect_uri |
Einer der Weiterleitungs-URIs, die für Ihr Projekt in der Cloud Console auf der Seite „Clients“ für die angegebene client_id aufgeführt sind. |
Die Verwendung von DPoP ist optional, wird aber für mehr Sicherheit empfohlen. Die Sicherheit von DPoP beruht darauf, dass der private Schlüssel auf ein einzelnes Gerät beschränkt ist. Wir empfehlen, ihn so zu speichern, dass er nicht vom Gerät kopiert werden kann, z. B. mithilfe von TPMs, Secure Enclaves oder anderen hardwaregestützten Schlüsselspeichern. Wenn Sie DPoP verwenden möchten, muss Ihre Anwendung für jede Anfrage an den Token-Endpunkt ein neues, eindeutiges DPoP-Proof-JWT generieren und als HTTP-Anfrageheader hinzufügen.
| Header | Erforderlich | Beschreibung |
|---|---|---|
DPoP |
Optional | Ein DPoP-Proof ist ein JWT, das den Besitz eines privaten Schlüssels belegt. Dies ist ein Header, kein Parameter. Falls angegeben, sind die zurückgegebenen Tokens an diesen Schlüssel gebunden. Für jede Anfrage muss ein neuer, eindeutiger Nachweis generiert werden, der die Claims htm (HTTP-Methode) und htu (HTTP-URI) enthält, die der Anfrage entsprechen. |
Das folgende Snippet zeigt eine Beispielanfrage:
POST /token HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik\ VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR\ nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE\ QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIj\ oiUE9TVCIsImh0dSI6Imh0dHBzOi8vc2VydmVyLmV4YW1wbGUuY29tL3Rva2VuIiwia\ WF0IjoxNTYyMjYyNjE2fQ.2-GxA6T8lP4vfrg8v-FdWP0A0zdrj8igiMLvqRMUvwnQg\ 4PtFLbdLXiOSsX0x7NVY-FNyJK70nfbV37xRZT3Lg code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7& client_id=your_client_id& redirect_uri=https%3A//developers.google.com/oauthplayground& grant_type=authorization_code
DPoP-Proof erstellen
In den folgenden Schritten wird gezeigt, wie Sie einen DPoP-Proof mit OpenSSL über die Befehlszeile erstellen:
- Generieren Sie ein EC-P-256-Schlüsselpaar:
openssl ecparam -name prime256v1 -genkey -noout -out dpop_private.pem openssl ec -in dpop_private.pem -pubout -out dpop_public.pem
- DPoP-Header erstellen:
Der Header muss die Anforderungen
typ,algundjwk(öffentlicher Schlüssel) enthalten. Die Wertexundysind die Base64Url-codierten Koordinaten Ihres öffentlichen EC-Schlüssels. Codieren Sie diesen JSON-Code mit Base64Url:{ "typ":"dpop+jwt", "alg":"ES256", "jwk": { "kty":"EC", "x":"YOUR_PUBLIC_KEY_X", "y":"YOUR_PUBLIC_KEY_Y", "crv":"P-256" } } - DPoP-Nutzlast erstellen:
Die Nutzlast muss
jti(eine eindeutige Kennung für die Anfrage),htm(HTTP-Methode, z.B.POST),htu(HTTP-URI, z.B.https://oauth2.googleapis.com/token) undiat(Ausstellungszeitpunkt) enthalten. Wenn Sie vom Server in einemDPoP-Nonce-Header in der Antwort auf eine vorherige Anfrage eine Nonce erhalten haben, müssen Sie diesen Nonce-Wert in einenonce-Anforderung einfügen. Der Nonce-Anspruch ist für den Austausch von Autorisierungscodes optional und wird nur verwendet, wenn der DPoP-Nonce-Header zuvor empfangen wurde. Codieren Sie diesen JSON-Code mit Base64Url:{ "jti":"JTI_VALUE", "htm":"POST", "htu":"https://oauth2.googleapis.com/token", "iat":YOUR_JWT_ISSUED_TIME, "nonce":"SERVER_PROVIDED_NONCE" }Der Wert
jtihängt vom Typ der Anzeigenplattform ab:- Bei Autorisierungscode-Austauschen muss der
jtider Base64Url-codierte SHA256-Hash des Autorisierungscodes sein:"jti":"BASE64URL(SHA256(AUTHORIZATION_CODE))". - Für den Austausch von Aktualisierungstokens muss die
jtieine eindeutige Kennung pro Anfrage sein:"jti":"YOUR_UNIQUE_PER_REQUEST_IDENTIFIER".
- Bei Autorisierungscode-Austauschen muss der
- Nachweis signieren:
Verketten Sie den codierten Header und die Nutzlast mit einem Punkt (
.) und signieren Sie das Ergebnis dann mit Ihrem privaten Schlüssel mithilfe von ES256. Beachten Sie, dass die Signatur für JWS in einem unformatierten, verkettetenR | S-Format vorliegen muss (64 Byte für P-256). Wenn Sie OpenSSL direkt verwenden, müssen Sie die standardmäßige ASN.1-DER-codierte Signatur in dieses Rohformat konvertieren.
Ein erfolgreicher Austausch wird durch eine 200 OK-Antwort mit den Tokens angezeigt. Wenn während des Austauschs ein gültiger DPoP-Nachweis verwendet wird, ist das von Google zurückgegebene Aktualisierungstoken per DPoP an Ihren Schlüssel gebunden, Zugriffstokens jedoch nicht. Zugriffstokens behalten den token_type von Bearer anstelle von DPoP bei.
Außerdem gibt Google in der Antwort einen DPoP-Nonce-HTTP-Header zurück.
Ihr Client muss diese Nonce im Cache speichern und sie in nachfolgenden Anfragen (z. B. beim Austausch eines Aktualisierungstokens gegen ein neues Zugriffstoken oder beim Aufrufen von DPoP-geschützten APIs) in den nonce-Claim des DPoP-Proofs einfügen. Durch die Verwendung dieser frühzeitig ausgegebenen Nonce können Sie einen zusätzlichen Roundtrip-Fehler (use_dpop_nonce) bei Ihrer nächsten Anfrage vermeiden.
DPoP-Nachweise müssen für Tokenaustauschanfragen enthalten sein, die mit DPoP-gebundenen Aktualisierungstokens gestellt werden.
Ein fehlgeschlagener Austausch tritt auf, wenn der Header DPoP fehlt, obwohl er erwartet wird, ungültig ist oder wenn der Nachweis einen anderen Schlüssel als den an das Token gebundenen Schlüssel verwendet. In diesen Fällen gibt der Server den Fehler 400 Bad Request zurück.
Wenn der DPoP-Proof nicht übereinstimmende htm- oder htu-Ansprüche, einen abgelaufenen iat, einen wiederverwendeten jti oder eine ungültige Signatur enthält, gibt Google den Fehlercode invalid_dpop_proof zurück.
Wenn eine DPoP-Nonce erforderlich ist, z. B. während eines Aktualisierungstoken-Austauschs, und im DPoP-Proof ein nonce-Claim fehlt oder der Nonce-Wert für den Server nicht akzeptabel ist (z. B. abgelaufen, bereits verwendet oder falsch), gibt Google den Fehlercode use_dpop_nonce zusammen mit dem HTTP-Header DPoP-Nonce zurück, der eine neue Nonce enthält, die Sie in einer nachfolgenden Anfrage verwenden können.
Bei anderen Fehlern wird möglicherweise invalid_grant zurückgegeben.
Google antwortet auf diese Anfrage mit einem JSON-Objekt, das ein kurzlebiges Zugriffstoken und ein Aktualisierungstoken enthält.
Das Aktualisierungstoken wird nur zurückgegeben, wenn Ihre Anwendung den Parameter access_type in der ersten Anfrage an den Autorisierungsserver von Google auf offline gesetzt hat.
Die Antwort umfasst die folgenden Felder:
| Felder | |
|---|---|
access_token |
Das Token, das Ihre Anwendung zur Autorisierung einer Google API-Anfrage sendet. |
expires_in |
Die verbleibende Lebensdauer des Zugriffstokens in Sekunden. |
refresh_token |
Ein Token, mit dem Sie ein neues Zugriffstoken abrufen können. Aktualisierungstokens sind gültig, bis der Nutzer den Zugriff widerruft oder das Aktualisierungstoken abläuft. Wenn DPoP verwendet wurde, ist das Aktualisierungstoken an den privaten Schlüssel gebunden, der zum Signieren des DPoP-Nachweises verwendet wurde.
Auch dieses Feld ist nur in dieser Antwort enthalten, wenn Sie den Parameter access_type in der ursprünglichen Anfrage an den Autorisierungsserver von Google auf offline festgelegt haben.
|
refresh_token_expires_in |
Die verbleibende Lebensdauer des Aktualisierungstokens in Sekunden. Dieser Wert wird nur festgelegt, wenn der Nutzer zeitbasierten Zugriff gewährt. |
scope |
Die Zugriffsbereiche, die vom access_token gewährt werden, ausgedrückt als Liste von durch Leerzeichen getrennten Strings, bei denen die Groß-/Kleinschreibung beachtet wird. |
token_type |
Der Typ des zurückgegebenen Tokens. Dieser Wert ist immer Bearer, auch wenn DPoP verwendet wird. |
Das folgende Snippet zeigt ein Beispiel für erfolgreiche Antwortheader und einen Antworttext, wenn DPoP verwendet wird:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
DPoP-Nonce: AN3XwJjZsjnb0ZuWkRlek8QU7wY-Zhf-5IP6tO0tORz0KgtDT1Bo8FX-w4nz3r5lnepI
{
"access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
"expires_in": 3920,
"token_type": "Bearer",
"scope": "https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly",
"refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
}Fehler
Wenn Sie den Autorisierungscode gegen ein Zugriffstoken austauschen, erhalten Sie möglicherweise den folgenden Fehler anstelle der erwarteten Antwort. In diesem Abschnitt sind häufige Fehlercodes und empfohlene Lösungen aufgeführt.
invalid_grant
Der angegebene Autorisierungscode ist ungültig oder hat das falsche Format. Fordern Sie einen neuen Code an, indem Sie den OAuth-Prozess neu starten, um den Nutzer noch einmal um seine Einwilligung zu bitten.
Schritt 6: Prüfen, welche Bereiche Nutzer gewährt haben
Wenn Sie mehrere Berechtigungen (Bereiche) anfordern, gewähren Nutzer Ihrer App möglicherweise nicht Zugriff auf alle. In deiner App muss geprüft werden, welche Bereiche tatsächlich gewährt wurden. Außerdem müssen Situationen, in denen einige Berechtigungen verweigert werden, ordnungsgemäß behandelt werden. In der Regel werden dazu die Funktionen deaktiviert, die auf diesen verweigerten Bereichen basieren.
Es gibt allerdings Ausnahmen. Bei Google Workspace Enterprise-Apps mit domainweiter Übertragung von Befugnissen oder Apps, die als Vertrauenswürdig gekennzeichnet sind, wird der Zustimmungsbildschirm für detaillierte Berechtigungen umgangen. Für diese Apps wird Nutzern der Bildschirm für die Einwilligung in detaillierte Berechtigungen nicht angezeigt. Stattdessen erhält Ihre App entweder alle angeforderten Bereiche oder keine.
Weitere Informationen finden Sie unter Umgang mit detaillierten Berechtigungen.
PHP
Mit der Methode getGrantedScope() können Sie prüfen, welche Bereiche der Nutzer gewährt hat:
// Space-separated string of granted scopes if it exists, otherwise null. $granted_scopes = $client->getOAuth2Service()->getGrantedScope(); // Determine which scopes user granted and build a dictionary $granted_scopes_dict = [ 'Drive' => str_contains($granted_scopes, Google\Service\Drive::DRIVE_METADATA_READONLY), 'Calendar' => str_contains($granted_scopes, Google\Service\Calendar::CALENDAR_READONLY) ];
Python
Das zurückgegebene credentials-Objekt hat das Attribut granted_scopes, das eine Liste der Bereiche ist, die der Nutzer Ihrer App gewährt hat.
credentials = flow.credentials flask.session['credentials'] = { 'token': credentials.token, 'refresh_token': credentials.refresh_token, 'granted_scopes': credentials.granted_scopes}
Mit der folgenden Funktion wird geprüft, welche Bereiche der Nutzer Ihrer App gewährt hat.
def check_granted_scopes(credentials): features = {} if 'https://www.googleapis.com/auth/drive.metadata.readonly' in credentials['granted_scopes']: features['drive'] = True else: features['drive'] = False if 'https://www.googleapis.com/auth/calendar.readonly' in credentials['granted_scopes']: features['calendar'] = True else: features['calendar'] = False return features
Ruby
Wenn Sie mehrere Bereiche gleichzeitig anfordern, prüfen Sie, welche Bereiche über das Attribut scope des Objekts credentials gewährt wurden.
# User authorized the request. Now, check which scopes were granted. if credentials.scope.include?(Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY) # User authorized read-only Drive activity permission. # Calling the APIs, etc else # User didn't authorize read-only Drive activity permission. # Update UX and application accordingly end # Check if user authorized Calendar read permission. if credentials.scope.include?(Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY) # User authorized Calendar read permission. # Calling the APIs, etc. else # User didn't authorize Calendar read permission. # Update UX and application accordingly end
Node.js
Wenn Sie mehrere Bereiche gleichzeitig anfordern, prüfen Sie, welche Bereiche über das Attribut scope des Objekts tokens gewährt wurden.
// User authorized the request. Now, check which scopes were granted. if (tokens.scope.includes('https://www.googleapis.com/auth/drive.metadata.readonly')) { // User authorized read-only Drive activity permission. // Calling the APIs, etc. } else { // User didn't authorize read-only Drive activity permission. // Update UX and application accordingly } // Check if user authorized Calendar read permission. if (tokens.scope.includes('https://www.googleapis.com/auth/calendar.readonly')) { // User authorized Calendar read permission. // Calling the APIs, etc. } else { // User didn't authorize Calendar read permission. // Update UX and application accordingly }
HTTP/REST
Wenn Sie prüfen möchten, ob der Nutzer Ihrer Anwendung Zugriff auf einen bestimmten Bereich gewährt hat, sehen Sie sich das Feld scope in der Antwort des Zugriffstokens an. Die Zugriffsbereiche, die durch das Zugriffstoken gewährt werden, ausgedrückt als Liste von durch Leerzeichen getrennten Strings, bei denen die Groß-/Kleinschreibung beachtet wird.
Die folgende Beispielantwort für ein Zugriffstoken zeigt beispielsweise, dass der Nutzer Ihrer Anwendung Zugriff auf die Berechtigungen für schreibgeschützte Drive-Aktivitäten und Kalendertermine gewährt hat:
{ "access_token": "1/fFAGRNJru1FTz70BzhT3Zg", "expires_in": 3920, "token_type": "Bearer", "scope": "https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly", "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI" }
Google APIs aufrufen
PHP
Führen Sie die folgenden Schritte aus, um das Zugriffstoken zum Aufrufen von Google APIs zu verwenden:
- Wenn Sie ein Zugriffstoken auf ein neues
Google\Client-Objekt anwenden müssen, z. B. wenn Sie das Zugriffstoken in einer Nutzersitzung gespeichert haben, verwenden Sie die MethodesetAccessToken:$client->setAccessToken($access_token); - Erstellen Sie ein Dienstobjekt für die API, die Sie aufrufen möchten. Sie erstellen ein Dienstobjekt, indem Sie dem Konstruktor für die API, die Sie aufrufen möchten, ein autorisiertes
Google\Client-Objekt übergeben. So rufen Sie beispielsweise die Drive API auf:$drive = new Google\Service\Drive($client); - Senden Sie Anfragen an den API-Dienst über die
vom Dienstobjekt bereitgestellte Schnittstelle.
So listen Sie beispielsweise die Dateien im Google Drive des authentifizierten Nutzers auf:
$files = $drive->files->listFiles(array());
Python
Nachdem Ihre Anwendung ein Zugriffstoken erhalten hat, kann sie dieses Token verwenden, um API-Anfragen im Namen eines bestimmten Nutzerkontos oder Dienstkontos zu autorisieren. Verwenden Sie die nutzerspezifischen Autorisierungsanmeldedaten, um ein Dienstobjekt für die API zu erstellen, die Sie aufrufen möchten. Verwenden Sie dann dieses Objekt, um autorisierte API-Anfragen zu stellen.
- Erstellen Sie ein Dienstobjekt für die API, die Sie aufrufen möchten. Sie erstellen ein Dienstobjekt, indem Sie die Methode
buildder Bibliothekgoogleapiclient.discoverymit dem Namen und der Version der API sowie den Nutzeranmeldedaten aufrufen: Beispiel für den Aufruf von Version 3 der Drive API:from googleapiclient.discovery import build drive = build('drive', 'v2', credentials=credentials)
- Senden Sie Anfragen an den API-Dienst über die vom Dienstobjekt bereitgestellte Schnittstelle.
So listen Sie beispielsweise die Dateien im Google Drive des authentifizierten Nutzers auf:
files = drive.files().list().execute()
Ruby
Nachdem Ihre Anwendung ein Zugriffstoken erhalten hat, kann sie dieses Token verwenden, um API-Anfragen im Namen eines bestimmten Nutzerkontos oder Dienstkontos zu senden. Verwenden Sie die nutzerspezifischen Autorisierungsanmeldedaten, um ein Dienstobjekt für die API zu erstellen, die Sie aufrufen möchten. Verwenden Sie dann dieses Objekt, um autorisierte API-Anfragen zu stellen.
- Erstellen Sie ein Dienstobjekt für die API, die Sie aufrufen möchten.
Beispiel für den Aufruf von Version 3 der Drive API:
drive = Google::Apis::DriveV3::DriveService.new
- Legen Sie die Anmeldedaten für den Dienst fest:
drive.authorization = credentials
- Senden Sie Anfragen an den API-Dienst über die Schnittstelle, die vom Dienstobjekt bereitgestellt wird.
So listen Sie beispielsweise die Dateien im Google Drive des authentifizierten Nutzers auf:
files = drive.list_files
Alternativ kann die Autorisierung pro Methode erfolgen, indem der Parameter options für eine Methode angegeben wird:
files = drive.list_files(options: { authorization: credentials })
Node.js
Nachdem Sie ein Zugriffstoken abgerufen und auf das Objekt OAuth2 festgelegt haben, können Sie mit dem Objekt Google APIs aufrufen. Ihre Anwendung kann dieses Token verwenden, um API-Anfragen im Namen eines bestimmten Nutzerkontos oder Dienstkontos zu autorisieren. Erstellen Sie ein Dienstobjekt für die API, die Sie aufrufen möchten.
Im folgenden Code wird beispielsweise die Google Drive API verwendet, um Dateinamen in der Drive-Ablage des Nutzers aufzulisten.
const { google } = require('googleapis'); // Example of using Google Drive API to list filenames in user's Drive. const drive = google.drive('v3'); drive.files.list({ auth: oauth2Client, pageSize: 10, fields: 'nextPageToken, files(id, name)', }, (err1, res1) => { if (err1) return console.log('The API returned an error: ' + err1); const files = res1.data.files; if (files.length) { console.log('Files:'); files.map((file) => { console.log(`${file.name} (${file.id})`); }); } else { console.log('No files found.'); } });
HTTP/REST
Nachdem Ihre Anwendung ein Zugriffstoken erhalten hat, können Sie damit im Namen eines bestimmten Nutzerkontos Aufrufe an eine Google API senden, sofern die von der API erforderlichen Zugriffsbereiche gewährt wurden. Fügen Sie dazu das Zugriffstoken in eine Anfrage an die API ein, indem Sie entweder einen access_token-Suchparameter oder einen Authorization-HTTP-Header-Bearer-Wert angeben. Wenn möglich, ist der HTTP-Header vorzuziehen, da Abfragestrings in Server-Logs sichtbar sein können. In den meisten Fällen können Sie eine Clientbibliothek verwenden, um Ihre Aufrufe an Google APIs einzurichten (z. B. beim Aufrufen der Drive Files API).
Sie können alle Google APIs ausprobieren und ihre Bereiche im OAuth 2.0 Playground ansehen.
HTTP-GET-Beispiele
Ein Aufruf des Endpunkts
drive.files (Drive Files API) mit dem HTTP-Header Authorization: Bearer könnte so aussehen: Beachten Sie, dass Sie Ihr eigenes Zugriffstoken angeben müssen:
GET /drive/v2/files HTTP/1.1 Host: www.googleapis.com Authorization: Bearer access_token
Hier ist ein Aufruf derselben API für den authentifizierten Nutzer mit dem Abfragestringparameter access_token:
GET https://www.googleapis.com/drive/v2/files?access_token=access_token
Beispiele für curl
Sie können diese Befehle mit der curl-Befehlszeilenanwendung testen. Hier ein Beispiel, in dem die HTTP-Header-Option (bevorzugt) verwendet wird:
curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files
Oder alternativ die Option für den Abfragestringparameter:
curl https://www.googleapis.com/drive/v2/files?access_token=access_token
Vollständiges Beispiel
Im folgenden Beispiel wird eine JSON-formatierte Liste von Dateien im Google Drive eines Nutzers ausgegeben, nachdem sich der Nutzer authentifiziert und der Anwendung die Erlaubnis erteilt hat, auf die Drive-Metadaten des Nutzers zuzugreifen.
PHP
So führen Sie das Beispiel aus:
- Fügen Sie in der API Console die URL des lokalen Computers zur Liste der Weiterleitungs-URLs hinzu, z. B.
http://localhost:8080. - Erstellen Sie ein neues Verzeichnis und wechseln Sie dorthin. Beispiel:
mkdir ~/php-oauth2-example cd ~/php-oauth2-example
- Installieren Sie die Google API-Clientbibliothek für PHP mit Composer:
composer require google/apiclient:^2.15.0
- Erstellen Sie die Dateien
index.phpundoauth2callback.phpmit folgendem Inhalt. - Führen Sie das Beispiel mit dem in PHP integrierten Testwebserver aus:
php -S localhost:8080 ~/php-oauth2-example
index.php
<?php require_once __DIR__.'/vendor/autoload.php'; session_start(); $client = new Google\Client(); $client->setAuthConfig('client_secret.json'); // User granted permission as an access token is in the session. if (isset($_SESSION['access_token']) && $_SESSION['access_token']) { $client->setAccessToken($_SESSION['access_token']); // Check if user granted Drive permission if ($_SESSION['granted_scopes_dict']['Drive']) { echo "Drive feature is enabled."; echo "</br>"; $drive = new Drive($client); $files = array(); $response = $drive->files->listFiles(array()); foreach ($response->files as $file) { echo "File: " . $file->name . " (" . $file->id . ")"; echo "</br>"; } } else { echo "Drive feature is NOT enabled."; echo "</br>"; } // Check if user granted Calendar permission if ($_SESSION['granted_scopes_dict']['Calendar']) { echo "Calendar feature is enabled."; echo "</br>"; } else { echo "Calendar feature is NOT enabled."; echo "</br>"; } } else { // Redirect users to outh2call.php which redirects users to Google OAuth 2.0 $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php'; header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL)); } ?>
oauth2callback.php
<?php require_once __DIR__.'/vendor/autoload.php'; session_start(); $client = new Google\Client(); // Required, call the setAuthConfig function to load authorization credentials from // client_secret.json file. $client->setAuthConfigFile('client_secret.json'); $client->setRedirectUri('http://' . $_SERVER['HTTP_HOST']. $_SERVER['PHP_SELF']); // Required, to set the scope value, call the addScope function. $client->addScope([Google\Service\Drive::DRIVE_METADATA_READONLY, Google\Service\Calendar::CALENDAR_READONLY]); // Enable incremental authorization. Recommended as a best practice. $client->setIncludeGrantedScopes(true); // Recommended, offline access will give you both an access and refresh token so that // your app can refresh the access token without user interaction. $client->setAccessType("offline"); // Generate a URL for authorization as it doesn't contain code and error if (!isset($_GET['code']) && !isset($_GET['error'])) { // Generate and set state value $state = bin2hex(random_bytes(16)); $client->setState($state); $_SESSION['state'] = $state; // Generate a url that asks permissions. $auth_url = $client->createAuthUrl(); header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL)); } // User authorized the request and authorization code is returned to exchange access and // refresh tokens. if (isset($_GET['code'])) { // Check the state value if (!isset($_GET['state']) || $_GET['state'] !== $_SESSION['state']) { die('State mismatch. Possible CSRF attack.'); } // Get access and refresh tokens (if access_type is offline) $token = $client->fetchAccessTokenWithAuthCode($_GET['code']); /** Save access and refresh token to the session variables. * ACTION ITEM: In a production app, you likely want to save the * refresh token in a secure persistent storage instead. */ $_SESSION['access_token'] = $token; $_SESSION['refresh_token'] = $client->getRefreshToken(); // Space-separated string of granted scopes if it exists, otherwise null. $granted_scopes = $client->getOAuth2Service()->getGrantedScope(); // Determine which scopes user granted and build a dictionary $granted_scopes_dict = [ 'Drive' => str_contains($granted_scopes, Google\Service\Drive::DRIVE_METADATA_READONLY), 'Calendar' => str_contains($granted_scopes, Google\Service\Calendar::CALENDAR_READONLY) ]; $_SESSION['granted_scopes_dict'] = $granted_scopes_dict; $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/'; header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL)); } // An error response e.g. error=access_denied if (isset($_GET['error'])) { echo "Error: ". $_GET['error']; } ?>
Python
In diesem Beispiel wird das Flask-Framework verwendet. Es wird eine Webanwendung unter http://localhost:8080 ausgeführt, mit der Sie den OAuth 2.0-Vorgang testen können. Wenn Sie diese URL aufrufen, sollten Sie fünf Links sehen:
- Drive API aufrufen:Dieser Link verweist auf eine Seite, die versucht, eine Beispiel-API-Anfrage auszuführen, wenn Nutzer die Berechtigung erteilt haben. Falls erforderlich, wird der Autorisierungsvorgang gestartet. Wenn der Vorgang erfolgreich war, wird auf der Seite die API-Antwort angezeigt.
- Mock-Seite zum Aufrufen der Calendar API:Dieser Link verweist auf eine Mock-Seite, die versucht, eine Beispielanfrage an die Calendar API auszuführen, wenn Nutzer die Berechtigung erteilt haben. Falls erforderlich, wird der Autorisierungsvorgang gestartet. Wenn der Vorgang erfolgreich war, wird auf der Seite die API-Antwort angezeigt.
- Authentifizierungsablauf direkt testen:Dieser Link verweist auf eine Seite, die versucht, den Nutzer durch den Autorisierungsablauf zu leiten. Die App fordert die Berechtigung an, autorisierte API-Anfragen im Namen des Nutzers zu senden.
- Aktuelle Anmeldedaten widerrufen:Dieser Link verweist auf eine Seite, auf der Berechtigungen widerrufen werden, die der Nutzer der Anwendung bereits gewährt hat.
- Flask-Sitzungsanmeldedaten löschen: Über diesen Link werden die in der Flask-Sitzung gespeicherten Autorisierungsanmeldedaten gelöscht. So können Sie sehen, was passieren würde, wenn ein Nutzer, der Ihrer App bereits die Berechtigung erteilt hat, versucht, eine API-Anfrage in einer neuen Sitzung auszuführen. Außerdem können Sie die API-Antwort sehen, die Ihre App erhalten würde, wenn ein Nutzer die Ihrer App erteilten Berechtigungen widerrufen hätte und Ihre App weiterhin versuchen würde, eine Anfrage mit einem widerrufenen Zugriffstoken zu autorisieren.
# -*- coding: utf-8 -*- import os import flask import json import requests import google.oauth2.credentials import google_auth_oauthlib.flow import googleapiclient.discovery # This variable specifies the name of a file that contains the OAuth 2.0 # information for this application, including its client_id and client_secret. CLIENT_SECRETS_FILE = "client_secret.json" # The OAuth 2.0 access scope allows for access to the # authenticated user's account and requires requests to use an SSL connection. SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly', 'https://www.googleapis.com/auth/calendar.readonly'] API_SERVICE_NAME = 'drive' API_VERSION = 'v2' app = flask.Flask(__name__) # Note: A secret key is included in the sample so that it works. # If you use this code in your application, replace this with a truly secret # key. See https://flask.palletsprojects.com/quickstart/#sessions. app.secret_key = 'REPLACE ME - this value is here as a placeholder.' @app.route('/') def index(): return print_index_table() @app.route('/drive') def drive_api_request(): if 'credentials' not in flask.session: return flask.redirect('authorize') features = flask.session['features'] if features['drive']: # Load client secrets from the server-side file. with open(CLIENT_SECRETS_FILE, 'r') as f: client_config = json.load(f)['web'] # Load user-specific credentials from browser session storage. session_credentials = flask.session['credentials'] # Reconstruct the credentials object. credentials = google.oauth2.credentials.Credentials( refresh_token=session_credentials.get('refresh_token'), scopes=session_credentials.get('granted_scopes'), token=session_credentials.get('token'), client_id=client_config.get('client_id'), client_secret=client_config.get('client_secret'), token_uri=client_config.get('token_uri')) drive = googleapiclient.discovery.build( API_SERVICE_NAME, API_VERSION, credentials=credentials) files = drive.files().list().execute() # Save credentials back to session in case access token was refreshed. flask.session['credentials'] = credentials_to_dict(credentials) return flask.jsonify(**files) else: # User didn't authorize read-only Drive activity permission. return '<p>Drive feature is not enabled.</p>' @app.route('/calendar') def calendar_api_request(): if 'credentials' not in flask.session: return flask.redirect('authorize') features = flask.session['features'] if features['calendar']: # User authorized Calendar read permission. # Calling the APIs, etc. return ('<p>User granted the Google Calendar read permission. '+ 'This sample code does not include code to call Calendar</p>') else: # User didn't authorize Calendar read permission. # Update UX and application accordingly return '<p>Calendar feature is not enabled.</p>' @app.route('/authorize') def authorize(): # Create flow instance to manage the OAuth 2.0 Authorization Grant Flow steps. flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file( CLIENT_SECRETS_FILE, scopes=SCOPES) # The URI created here must exactly match one of the authorized redirect URIs # for the OAuth 2.0 client, which you configured in the API Console. If this # value doesn't match an authorized URI, you will get a 'redirect_uri_mismatch' # error. flow.redirect_uri = flask.url_for('oauth2callback', _external=True) authorization_url, state = flow.authorization_url( # Enable offline access so that you can refresh an access token without # re-prompting the user for permission. Recommended for web server apps. access_type='offline', # Enable incremental authorization. Recommended as a best practice. include_granted_scopes='true') # Store the state so the callback can verify the auth server response. flask.session['state'] = state return flask.redirect(authorization_url) @app.route('/oauth2callback') def oauth2callback(): # Specify the state when creating the flow in the callback so that it can # verified in the authorization server response. state = flask.session['state'] flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file( CLIENT_SECRETS_FILE, scopes=SCOPES, state=state) flow.redirect_uri = flask.url_for('oauth2callback', _external=True) # Use the authorization server's response to fetch the OAuth 2.0 tokens. authorization_response = flask.request.url flow.fetch_token(authorization_response=authorization_response) # Store credentials in the session. # ACTION ITEM: In a production app, you likely want to save these # credentials in a persistent database instead. credentials = flow.credentials credentials = credentials_to_dict(credentials) flask.session['credentials'] = credentials # Check which scopes user granted features = check_granted_scopes(credentials) flask.session['features'] = features return flask.redirect('/') @app.route('/revoke') def revoke(): if 'credentials' not in flask.session: return ('You need to <a href="/authorize">authorize</a> before ' + 'testing the code to revoke credentials.') # Load client secrets from the server-side file. with open(CLIENT_SECRETS_FILE, 'r') as f: client_config = json.load(f)['web'] # Load user-specific credentials from the session. session_credentials = flask.session['credentials'] # Reconstruct the credentials object. credentials = google.oauth2.credentials.Credentials( refresh_token=session_credentials.get('refresh_token'), scopes=session_credentials.get('granted_scopes'), token=session_credentials.get('token'), client_id=client_config.get('client_id'), client_secret=client_config.get('client_secret'), token_uri=client_config.get('token_uri')) revoke = requests.post('https://oauth2.googleapis.com/revoke', params={'token': credentials.token}, headers = {'content-type': 'application/x-www-form-urlencoded'}) status_code = getattr(revoke, 'status_code') if status_code == 200: # Clear the user's session credentials after successful revocation if 'credentials' in flask.session: del flask.session['credentials'] del flask.session['features'] return('Credentials successfully revoked.' + print_index_table()) else: return('An error occurred.' + print_index_table()) @app.route('/clear') def clear_credentials(): if 'credentials' in flask.session: del flask.session['credentials'] return ('Credentials have been cleared.<br><br>' + print_index_table()) def credentials_to_dict(credentials): return {'token': credentials.token, 'refresh_token': credentials.refresh_token, 'granted_scopes': credentials.granted_scopes} def check_granted_scopes(credentials): features = {} if 'https://www.googleapis.com/auth/drive.metadata.readonly' in credentials['granted_scopes']: features['drive'] = True else: features['drive'] = False if 'https://www.googleapis.com/auth/calendar.readonly' in credentials['granted_scopes']: features['calendar'] = True else: features['calendar'] = False return features def print_index_table(): return ('<table>' + '<tr><td><a href="/authorize">Test the auth flow directly</a></td>' + '<td>Go directly to the authorization flow. If there are stored ' + ' credentials, you still might not be prompted to reauthorize ' + ' the application.</td></tr>' + '<tr><td><a href="/drive">Call Drive API directly</a></td>' + '<td> Use stored credentials to call the API, you still might not be prompted to reauthorize ' + ' the application.</td></tr>' + '<tr><td><a href="/calendar">Call Calendar API directly</a></td>' + '<td> Use stored credentials to call the API, you still might not be prompted to reauthorize ' + ' the application.</td></tr>' + '<tr><td><a href="/revoke">Revoke current credentials</a></td>' + '<td>Revoke the access token associated with the current user ' + ' session. After revoking credentials, if you go to the test ' + ' page, you should see an <code>invalid_grant</code> error.' + '</td></tr>' + '<tr><td><a href="/clear">Clear Flask session credentials</a></td>' + '<td>Clear the access token currently stored in the user session. ' + ' After clearing the token, if you <a href="/authorize">authorize</a> ' + ' again, you should go back to the auth flow.' + '</td></tr></table>') if __name__ == '__main__': # When running locally, disable OAuthlib's HTTPs verification. # ACTION ITEM for developers: # When running in production *do not* leave this option enabled. os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1' # This disables the requested scopes and granted scopes check. # If users only grant partial request, the warning would not be thrown. os.environ['OAUTHLIB_RELAX_TOKEN_SCOPE'] = '1' # Specify a hostname and port that are set as a valid redirect URI # for your API project in the Google API Console. app.run('localhost', 8080, debug=True)
Ruby
In diesem Beispiel wird das Sinatra-Framework verwendet.
require 'googleauth' require 'googleauth/web_user_authorizer' require 'googleauth/stores/redis_token_store' require 'google/apis/drive_v3' require 'google/apis/calendar_v3' require 'sinatra' configure do enable :sessions # Required, call the from_file method to retrieve the client ID from a # client_secret.json file. set :client_id, Google::Auth::ClientId.from_file('/path/to/client_secret.json') # Required, scope value # Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar. scope = ['Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY', 'Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY'] # Required, Authorizers require a storage instance to manage long term persistence of # access and refresh tokens. set :token_store, Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new) # Required, indicate where the API server will redirect the user after the user completes # the authorization flow. The redirect URI is required. The value must exactly # match one of the authorized redirect URIs for the OAuth 2.0 client, which you # configured in the API Console. If this value doesn't match an authorized URI, # you will get a 'redirect_uri_mismatch' error. set :callback_uri, '/oauth2callback' # To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI # from the client_secret.json file. To get these credentials for your application, visit # https://console.cloud.google.com/apis/credentials. set :authorizer, Google::Auth::WebUserAuthorizer.new(settings.client_id, settings.scope, settings.token_store, callback_uri: settings.callback_uri) end get '/' do # NOTE: Assumes the user is already authenticated to the app user_id = request.session['user_id'] # Fetch stored credentials for the user from the given request session. # nil if none present credentials = settings.authorizer.get_credentials(user_id, request) if credentials.nil? # Generate a url that asks the user to authorize requested scope(s). # Then, redirect user to the url. redirect settings.authorizer.get_authorization_url(request: request) end # User authorized the request. Now, check which scopes were granted. if credentials.scope.include?(Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY) # User authorized read-only Drive activity permission. # Example of using Google Drive API to list filenames in user's Drive. drive = Google::Apis::DriveV3::DriveService.new files = drive.list_files(options: { authorization: credentials }) "<pre>#{JSON.pretty_generate(files.to_h)}</pre>" else # User didn't authorize read-only Drive activity permission. # Update UX and application accordingly end # Check if user authorized Calendar read permission. if credentials.scope.include?(Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY) # User authorized Calendar read permission. # Calling the APIs, etc. else # User didn't authorize Calendar read permission. # Update UX and application accordingly end end # Receive the callback from Google's OAuth 2.0 server. get '/oauth2callback' do # Handle the result of the oauth callback. Defers the exchange of the code by # temporarily stashing the results in the user's session. target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request) redirect target_url end
Node.js
So führen Sie das Beispiel aus:
-
Fügen Sie in der API Console die URL des lokalen Computers zur Liste der Weiterleitungs-URLs hinzu, z. B.
http://localhost. - Achten Sie darauf, dass Sie die Wartungs-LTS, die aktive LTS oder die aktuelle Version von Node.js installiert haben.
-
Erstellen Sie ein neues Verzeichnis und wechseln Sie dorthin. Beispiel:
mkdir ~/nodejs-oauth2-example cd ~/nodejs-oauth2-example
-
Installieren Sie die Google API-Clientbibliothek für Node.js mit npm:
npm install googleapis
-
Erstellen Sie die Dateien
main.jsmit folgendem Inhalt. -
Führen Sie das Beispiel aus:
node .\main.js
main.js
const http = require('http'); const https = require('https'); const url = require('url'); const { google } = require('googleapis'); const crypto = require('crypto'); const express = require('express'); const session = require('express-session'); /** * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI. * To get these credentials for your application, visit * https://console.cloud.google.com/apis/credentials. */ const oauth2Client = new google.auth.OAuth2( YOUR_CLIENT_ID, YOUR_CLIENT_SECRET, YOUR_REDIRECT_URL ); // Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar. const scopes = [ 'https://www.googleapis.com/auth/drive.metadata.readonly', 'https://www.googleapis.com/auth/calendar.readonly' ]; /* Global variable that stores user credential in this code example. * ACTION ITEM for developers: * Store user's refresh token in your data store if * incorporating this code into your real app. * For more information on handling refresh tokens, * see https://github.com/googleapis/google-api-nodejs-client#handling-refresh-tokens */ let userCredential = null; async function main() { const app = express(); app.use(session({ secret: 'your_secure_secret_key', // Replace with a strong secret resave: false, saveUninitialized: false, })); // Example on redirecting user to Google's OAuth 2.0 server. app.get('/', async (req, res) => { // Generate a secure random state value. const state = crypto.randomBytes(32).toString('hex'); // Store state in the session req.session.state = state; // Generate a url that asks permissions for the Drive activity and Google Calendar scope const authorizationUrl = oauth2Client.generateAuthUrl({ // 'online' (default) or 'offline' (gets refresh_token) access_type: 'offline', /** Pass in the scopes array defined above. * Alternatively, if only one scope is needed, you can pass a scope URL as a string */ scope: scopes, // Enable incremental authorization. Recommended as a best practice. include_granted_scopes: true, // Include the state parameter to reduce the risk of CSRF attacks. state: state }); res.redirect(authorizationUrl); }); // Receive the callback from Google's OAuth 2.0 server. app.get('/oauth2callback', async (req, res) => { // Handle the OAuth 2.0 server response let q = url.parse(req.url, true).query; if (q.error) { // An error response e.g. error=access_denied console.log('Error:' + q.error); } else if (q.state !== req.session.state) { //check state value console.log('State mismatch. Possible CSRF attack'); res.end('State mismatch. Possible CSRF attack'); } else { // Get access and refresh tokens (if access_type is offline) let { tokens } = await oauth2Client.getToken(q.code); oauth2Client.setCredentials(tokens); /** Save credential to the global variable in case access token was refreshed. * ACTION ITEM: In a production app, you likely want to save the refresh token * in a secure persistent database instead. */ userCredential = tokens; // User authorized the request. Now, check which scopes were granted. if (tokens.scope.includes('https://www.googleapis.com/auth/drive.metadata.readonly')) { // User authorized read-only Drive activity permission. // Example of using Google Drive API to list filenames in user's Drive. const drive = google.drive('v3'); drive.files.list({ auth: oauth2Client, pageSize: 10, fields: 'nextPageToken, files(id, name)', }, (err1, res1) => { if (err1) return console.log('The API returned an error: ' + err1); const files = res1.data.files; if (files.length) { console.log('Files:'); files.map((file) => { console.log(`${file.name} (${file.id})`); }); } else { console.log('No files found.'); } }); } else { // User didn't authorize read-only Drive activity permission. // Update UX and application accordingly } // Check if user authorized Calendar read permission. if (tokens.scope.includes('https://www.googleapis.com/auth/calendar.readonly')) { // User authorized Calendar read permission. // Calling the APIs, etc. } else { // User didn't authorize Calendar read permission. // Update UX and application accordingly } } }); // Example on revoking a token app.get('/revoke', async (req, res) => { // Build the string for the POST request let postData = "token=" + userCredential.access_token; // Options for POST request to Google's OAuth 2.0 server to revoke a token let postOptions = { host: 'oauth2.googleapis.com', port: '443', path: '/revoke', method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': Buffer.byteLength(postData) } }; // Set up the request const postReq = https.request(postOptions, function (res) { res.setEncoding('utf8'); res.on('data', d => { console.log('Response: ' + d); }); }); postReq.on('error', error => { console.log(error) }); // Post the request with data postReq.write(postData); postReq.end(); }); const server = http.createServer(app); server.listen(8080); } main().catch(console.error);
HTTP/REST
In diesem Python-Beispiel werden das Flask-Framework und die Requests-Bibliothek verwendet, um den OAuth 2.0-Webablauf zu demonstrieren. Wir empfehlen, für diesen Ablauf die Google API-Clientbibliothek für Python zu verwenden. (Im Beispiel auf dem Tab „Python“ wird die Clientbibliothek verwendet.)
import json import flask import requests app = flask.Flask(__name__) # To get these credentials (CLIENT_ID CLIENT_SECRET) and for your application, visit # https://console.cloud.google.com/apis/credentials. CLIENT_ID = '123456789.apps.googleusercontent.com' CLIENT_SECRET = 'abc123' # Read from a file or environmental variable in a real app # Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar. SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly' # Indicate where the API server will redirect the user after the user completes # the authorization flow. The redirect URI is required. The value must exactly # match one of the authorized redirect URIs for the OAuth 2.0 client, which you # configured in the API Console. If this value doesn't match an authorized URI, # you will get a 'redirect_uri_mismatch' error. REDIRECT_URI = 'http://example.com/oauth2callback' @app.route('/') def index(): if 'credentials' not in flask.session: return flask.redirect(flask.url_for('oauth2callback')) credentials = json.loads(flask.session['credentials']) if credentials['expires_in'] <= 0: return flask.redirect(flask.url_for('oauth2callback')) else: # User authorized the request. Now, check which scopes were granted. if 'https://www.googleapis.com/auth/drive.metadata.readonly' in credentials['scope']: # User authorized read-only Drive activity permission. # Example of using Google Drive API to list filenames in user's Drive. headers = {'Authorization': 'Bearer {}'.format(credentials['access_token'])} req_uri = 'https://www.googleapis.com/drive/v2/files' r = requests.get(req_uri, headers=headers).text else: # User didn't authorize read-only Drive activity permission. # Update UX and application accordingly r = 'User did not authorize Drive permission.' # Check if user authorized Calendar read permission. if 'https://www.googleapis.com/auth/calendar.readonly' in credentials['scope']: # User authorized Calendar read permission. # Calling the APIs, etc. r += 'User authorized Calendar permission.' else: # User didn't authorize Calendar read permission. # Update UX and application accordingly r += 'User did not authorize Calendar permission.' return r @app.route('/oauth2callback') def oauth2callback(): if 'code' not in flask.request.args: state = str(uuid.uuid4()) flask.session['state'] = state # Generate a url that asks permissions for the Drive activity # and Google Calendar scope. Then, redirect user to the url. auth_uri = ('https://accounts.google.com/o/oauth2/v2/auth?response_type=code' '&client_id={}&redirect_uri={}&scope={}&state={}').format(CLIENT_ID, REDIRECT_URI, SCOPE, state) return flask.redirect(auth_uri) else: if 'state' not in flask.request.args or flask.request.args['state'] != flask.session['state']: return 'State mismatch. Possible CSRF attack.', 400 auth_code = flask.request.args.get('code') data = {'code': auth_code, 'client_id': CLIENT_ID, 'client_secret': CLIENT_SECRET, 'redirect_uri': REDIRECT_URI, 'grant_type': 'authorization_code'} # Exchange authorization code for access and refresh tokens (if access_type is offline) r = requests.post('https://oauth2.googleapis.com/token', data=data) flask.session['credentials'] = r.text return flask.redirect(flask.url_for('index')) if __name__ == '__main__': import uuid app.secret_key = str(uuid.uuid4()) app.debug = False app.run()
Validierungsregeln für Weiterleitungs-URIs
Google wendet die folgenden Validierungsregeln auf Weiterleitungs-URIs an, um Entwicklern dabei zu helfen, ihre Anwendungen zu schützen. Ihre Weiterleitungs-URIs müssen diesen Regeln entsprechen. Die Definitionen von Domain, Host, Pfad, Abfrage, Schema und Nutzerinformationen, die in diesen Regeln verwendet werden, finden Sie in RFC 3986, Abschnitt 3.
| Validierungsregeln | |
|---|---|
| Schema |
Weiterleitungs-URIs müssen das HTTPS-Schema verwenden, nicht das einfache HTTP. Localhost-URIs (einschließlich Localhost-IP-Adress-URIs) sind von dieser Regel ausgenommen. |
| Moderator:in |
Hosts dürfen keine unformatierten IP-Adressen sein. Localhost-IP-Adressen sind von dieser Regel ausgenommen. |
| Domain |
“googleusercontent.com” sein.goo.gl) enthalten, es sei denn, die App ist Inhaber der Domain. Wenn eine App, die eine Kurz-Domain besitzt, eine Weiterleitung zu dieser Domain vornimmt, muss der Weiterleitungs-URI entweder “/google-callback/” im Pfad enthalten oder mit “/google-callback” enden. |
| Userinfo |
Weiterleitungs-URIs dürfen die Unterkomponente „userinfo“ nicht enthalten. |
| Pfad |
Weiterleitungs-URIs dürfen keine Pfaddurchquerung (auch Verzeichnis-Backtracking genannt) enthalten, die durch |
| Abfrage |
Weiterleitungs-URIs dürfen keine offenen Weiterleitungen enthalten. |
| Fragment |
Weiterleitungs-URIs dürfen keine Fragmentkomponente enthalten. |
| Zeichen |
Weiterleitungs-URIs dürfen bestimmte Zeichen nicht enthalten, darunter:
|
Inkrementelle Autorisierung
Im OAuth 2.0-Protokoll fordert Ihre App die Autorisierung für den Zugriff auf Ressourcen an, die durch Bereiche identifiziert werden. Es gilt als Best Practice für die Nutzerfreundlichkeit, die Autorisierung für Ressourcen erst dann anzufordern, wenn sie benötigt werden. Um diese Vorgehensweise zu ermöglichen, unterstützt der Autorisierungsserver von Google die inkrementelle Autorisierung. Mit dieser Funktion können Sie Bereiche nach Bedarf anfordern. Wenn der Nutzer die Berechtigung für den neuen Bereich erteilt, wird ein Autorisierungscode zurückgegeben, der gegen ein Token eingetauscht werden kann, das alle Bereiche enthält, die der Nutzer dem Projekt gewährt hat.
Eine App, mit der Nutzer Musikstücke anhören und Mixe erstellen können, benötigt bei der Anmeldung möglicherweise nur wenige Ressourcen, vielleicht nur den Namen der Person, die sich anmeldet. Zum Speichern eines fertigen Mixes ist jedoch Zugriff auf Google Drive erforderlich. Die meisten Nutzer würden es als natürlich empfinden, wenn sie erst dann um Zugriff auf ihr Google Drive gebeten werden, wenn die App ihn tatsächlich benötigt.
In diesem Fall kann die App bei der Anmeldung die Bereiche openid und profile anfordern, um eine einfache Anmeldung durchzuführen, und dann später bei der ersten Anfrage zum Speichern eines Mixes den Bereich https://www.googleapis.com/auth/drive.file anfordern.
Wenn Sie die inkrementelle Autorisierung implementieren möchten, führen Sie den normalen Ablauf zum Anfordern eines Zugriffstokens aus. Achten Sie aber darauf, dass die Autorisierungsanfrage zuvor gewährte Bereiche enthält. So muss Ihre App nicht mehrere Zugriffstokens verwalten.
Für ein Zugriffstoken, das über eine inkrementelle Autorisierung abgerufen wird, gelten die folgenden Regeln:
- Das Token kann verwendet werden, um auf Ressourcen zuzugreifen, die einem der Bereiche entsprechen, die in die neue, kombinierte Autorisierung einbezogen wurden.
- Wenn Sie das Aktualisierungstoken für die kombinierte Autorisierung verwenden, um ein Zugriffstoken zu erhalten, steht das Zugriffstoken für die kombinierte Autorisierung und kann für alle in der Antwort enthaltenen
scope-Werte verwendet werden. - Die kombinierte Autorisierung umfasst alle Bereiche, die der Nutzer dem API-Projekt gewährt hat, auch wenn die Gewährungen von verschiedenen Clients angefordert wurden. Wenn ein Nutzer beispielsweise über den Desktop-Client einer Anwendung Zugriff auf einen Bereich gewährt und dann über einen mobilen Client Zugriff auf einen anderen Bereich derselben Anwendung gewährt, umfasst die kombinierte Autorisierung beide Bereiche.
- Wenn Sie ein Token widerrufen, das eine kombinierte Autorisierung darstellt, wird der Zugriff auf alle Bereiche dieser Autorisierung im Namen des zugehörigen Nutzers gleichzeitig widerrufen.
In den sprachspezifischen Codebeispielen in Schritt 1: Autorisierungsweiterleitung zum OAuth 2.0-Server von Google festlegen wird die inkrementelle Autorisierung verwendet. Die folgenden Codebeispiele zeigen auch den Code, den Sie für die inkrementelle Autorisierung hinzufügen müssen.
PHP
$client->setIncludeGrantedScopes(true);Python
Legen Sie in Python das Schlüsselwortargument include_granted_scopes auf true fest, damit eine Autorisierungsanfrage zuvor gewährte Bereiche enthält. Es ist sehr wahrscheinlich, dass include_granted_scopes nicht das einzige Keyword-Argument ist, das Sie festlegen, wie im folgenden Beispiel gezeigt.
authorization_url, state = flow.authorization_url( # Enable offline access so that you can refresh an access token without # re-prompting the user for permission. Recommended for web server apps. access_type='offline', # Enable incremental authorization. Recommended as a best practice. include_granted_scopes='true')
Ruby
auth_client.update!( :additional_parameters => {"include_granted_scopes" => "true"} )
Node.js
const authorizationUrl = oauth2Client.generateAuthUrl({ // 'online' (default) or 'offline' (gets refresh_token) access_type: 'offline', /** Pass in the scopes array defined above. * Alternatively, if only one scope is needed, you can pass a scope URL as a string */ scope: scopes, // Enable incremental authorization. Recommended as a best practice. include_granted_scopes: true });
HTTP/REST
GET https://accounts.google.com/o/oauth2/v2/auth? client_id=your_client_id& response_type=code& state=state_parameter_passthrough_value& scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly%20https%3A//www.googleapis.com/auth/calendar.readonly& redirect_uri=https%3A//developers.google.com/oauthplayground& prompt=consent& include_granted_scopes=true
Zugriffstoken aktualisieren (Offlinezugriff)
Zugriffstokens laufen regelmäßig ab und werden zu ungültigen Anmeldedaten für eine zugehörige API-Anfrage. Sie können ein Zugriffstoken aktualisieren, ohne den Nutzer um Erlaubnis zu bitten (auch wenn der Nutzer nicht anwesend ist), wenn Sie Offlinezugriff auf die mit dem Token verknüpften Bereiche angefordert haben.
- Wenn Sie eine Google API-Clientbibliothek verwenden, aktualisiert das Clientobjekt das Zugriffstoken nach Bedarf, solange Sie dieses Objekt für den Offlinezugriff konfigurieren.
- Wenn Sie keine Clientbibliothek verwenden, müssen Sie den HTTP-Suchparameter
access_typeaufofflinesetzen, wenn Sie den Nutzer zum OAuth 2.0-Server von Google weiterleiten. In diesem Fall gibt der Autorisierungsserver von Google ein Aktualisierungstoken zurück, wenn Sie einen Autorisierungscode gegen ein Zugriffstoken austauschen. Wenn das Zugriffstoken abläuft (oder zu einem anderen Zeitpunkt), können Sie ein Aktualisierungstoken verwenden, um ein neues Zugriffstoken zu erhalten.
Das Anfordern des Offlinezugriffs ist für jede Anwendung erforderlich, die auf eine Google API zugreifen muss, wenn der Nutzer nicht anwesend ist. Beispielsweise muss eine App, die Sicherungsdienste ausführt oder Aktionen zu vordefinierten Zeiten ausführt, ihr Zugriffstoken aktualisieren können, wenn der Nutzer nicht anwesend ist. Der Standardzugriffsstil heißt online.
Serverseitige Webanwendungen, installierte Anwendungen und Geräte erhalten während des Autorisierungsprozesses Aktualisierungstokens. Aktualisierungstokens werden in clientseitigen (JavaScript-)Webanwendungen normalerweise nicht verwendet.
PHP
Wenn Ihre Anwendung Offlinezugriff auf eine Google API benötigt, legen Sie den Zugriffstyp des API-Clients auf offline fest:
$client->setAccessType("offline");Nachdem ein Nutzer Offlinezugriff auf die angeforderten Bereiche gewährt hat, können Sie den API-Client weiterhin verwenden, um im Namen des Nutzers auf Google APIs zuzugreifen, wenn der Nutzer offline ist. Das Clientobjekt aktualisiert das Zugriffstoken nach Bedarf.
Python
Setze in Python das Schlüsselwortargument access_type auf offline, damit du das Zugriffstoken aktualisieren kannst, ohne den Nutzer noch einmal um Erlaubnis bitten zu müssen. Es ist sehr wahrscheinlich, dass access_type nicht das einzige Keyword-Argument ist, das Sie festlegen, wie im folgenden Beispiel gezeigt.
authorization_url, state = flow.authorization_url( # Enable offline access so that you can refresh an access token without # re-prompting the user for permission. Recommended for web server apps. access_type='offline', # Enable incremental authorization. Recommended as a best practice. include_granted_scopes='true')
Nachdem ein Nutzer Offlinezugriff auf die angeforderten Bereiche gewährt hat, können Sie den API-Client weiterhin verwenden, um im Namen des Nutzers auf Google APIs zuzugreifen, wenn der Nutzer offline ist. Das Clientobjekt aktualisiert das Zugriffstoken nach Bedarf.
Ruby
Wenn Ihre Anwendung Offlinezugriff auf eine Google API benötigt, legen Sie den Zugriffstyp des API-Clients auf offline fest:
auth_client.update!( :additional_parameters => {"access_type" => "offline"} )
Nachdem ein Nutzer Offlinezugriff auf die angeforderten Bereiche gewährt hat, können Sie den API-Client weiterhin verwenden, um im Namen des Nutzers auf Google APIs zuzugreifen, wenn der Nutzer offline ist. Das Clientobjekt aktualisiert das Zugriffstoken nach Bedarf.
Node.js
Wenn Ihre Anwendung Offlinezugriff auf eine Google API benötigt, legen Sie den Zugriffstyp des API-Clients auf offline fest:
const authorizationUrl = oauth2Client.generateAuthUrl({ // 'online' (default) or 'offline' (gets refresh_token) access_type: 'offline', /** Pass in the scopes array defined above. * Alternatively, if only one scope is needed, you can pass a scope URL as a string */ scope: scopes, // Enable incremental authorization. Recommended as a best practice. include_granted_scopes: true });
Nachdem ein Nutzer Offlinezugriff auf die angeforderten Bereiche gewährt hat, können Sie den API-Client weiterhin verwenden, um im Namen des Nutzers auf Google APIs zuzugreifen, wenn der Nutzer offline ist. Das Clientobjekt aktualisiert das Zugriffstoken nach Bedarf.
Zugriffstokens laufen ab. Diese Bibliothek verwendet automatisch ein Aktualisierungstoken, um ein neues Zugriffstoken abzurufen, wenn es bald abläuft. Eine einfache Möglichkeit, immer die neuesten Tokens zu speichern, ist die Verwendung des Tokens-Ereignisses:
oauth2Client.on('tokens', (tokens) => { if (tokens.refresh_token) { // store the refresh_token in your secure persistent database console.log(tokens.refresh_token); } console.log(tokens.access_token); });
Dieses Token-Ereignis tritt nur bei der ersten Autorisierung auf. Sie müssen access_type auf offline setzen, wenn Sie die Methode generateAuthUrl aufrufen, um das Aktualisierungstoken zu erhalten. Wenn Sie Ihrer App bereits die erforderlichen Berechtigungen erteilt haben, ohne die entsprechenden Einschränkungen für den Erhalt eines Aktualisierungstokens festzulegen, müssen Sie die Anwendung neu autorisieren, um ein neues Aktualisierungstoken zu erhalten.
Wenn Sie die refresh_token zu einem späteren Zeitpunkt festlegen möchten, können Sie die Methode setCredentials verwenden:
oauth2Client.setCredentials({ refresh_token: `STORED_REFRESH_TOKEN` });
Sobald der Client ein Aktualisierungstoken hat, werden Zugriffstokens beim nächsten Aufruf der API automatisch abgerufen und aktualisiert.
HTTP/REST
Wenn Sie ein Zugriffstoken aktualisieren möchten, sendet Ihre Anwendung eine HTTPS-POST-Anfrage an den Autorisierungsserver von Google (https://oauth2.googleapis.com/token). Diese Anfrage enthält die folgenden Parameter im Anfragetext:
| Name | Wert |
|---|---|
client_id |
Die Client-ID, die Sie über die API Console erhalten haben. |
client_secret |
Optional
Der Clientschlüssel, der über die API Console abgerufen wurde. |
grant_type |
Wie in der OAuth 2.0-Spezifikation definiert, muss der Wert dieses Felds auf refresh_token gesetzt werden. |
refresh_token |
Das Aktualisierungstoken, das beim Austausch des Autorisierungscodes zurückgegeben wurde. |
Die Verwendung von DPoP ist optional, wird aber für mehr Sicherheit empfohlen. Wenn Sie DPoP mit einem Aktualisierungstoken verwenden möchten, muss Ihre Anwendung für jede Anfrage an den Token-Endpunkt ein neues, eindeutiges DPoP-Proof-JWT generieren. Dieser Nachweis muss mit demselben privaten Schlüssel signiert werden, der beim ersten Austausch des Autorisierungscodes verwendet wurde. Ihre Anwendung fügt den Nachweis als HTTP-Anfrageheader hinzu.
| Header | Erforderlich | Beschreibung |
|---|---|---|
DPoP |
Optional | Ein DPoP-Proof ist ein JWT, das den Besitz eines privaten Schlüssels belegt. Dies ist ein Header, kein Parameter. Falls angegeben, sind die zurückgegebenen Tokens an diesen Schlüssel gebunden. Für jede Anfrage muss ein neuer, eindeutiger Nachweis generiert werden, der die Claims htm (HTTP-Methode) und htu (HTTP-URI) enthält, die der Anfrage entsprechen. |
Das folgende Snippet zeigt eine Beispielanfrage:
POST /token HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded DPoP: DPOP_PROOF_JWT client_id=your_client_id& refresh_token=refresh_token& grant_type=refresh_token
Wenn Sie DPoP mit einem Aktualisierungstoken verwenden möchten, müssen Sie für die Anfrage ein neues, eindeutiges DPoP-Proof-JWT generieren. Eine detaillierte Anleitung zum Generieren des Schlüsselpaars und zum Erstellen des JWT finden Sie unter DPoP-Proof erstellen.
Ein erfolgreicher Austausch wird durch eine 200 OK-Antwort mit einem neuen Zugriffstoken angezeigt. Wenn DPoP verwendet wird, ist der token_type Bearer. Eine erfolgreiche Antwort bestätigt, dass der DPoP-Proof für das Aktualisierungstoken akzeptiert wurde. Google kann in der Antwort auch einen neuen HTTP-Header DPoP-Nonce zurückgeben. Wenn er zurückgegeben wird, muss Ihr Client diese Nonce im Cache speichern und sie in nachfolgenden Anfragen in den nonce-Claim des DPoP-Proofs aufnehmen.
Ein fehlgeschlagener Austausch tritt auf, wenn der DPoP-Header fehlt, ungültig ist oder einen falschen Schlüssel verwendet. Weitere Informationen zu bestimmten DPoP-Fehlercodes und zur Verarbeitung von Nonces finden Sie unter Fehlgeschlagener Austausch.
Das folgende Snippet zeigt ein Beispiel für erfolgreiche Antwortheader und einen Antworttext, wenn DPoP verwendet wird:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
DPoP-Nonce: AN3XwJjZsjnb0ZuWkRlek8QU7wY-Zhf-5IP6tO0tORz0KgtDT1Bo8FX-w4nz3r5lnepI
{
"access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
"expires_in": 3920,
"scope": "https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly",
"token_type": "Bearer"
}Beachten Sie, dass die Anzahl der ausgestellten Aktualisierungstokens begrenzt ist. Es gibt ein Limit pro Client/Nutzer-Kombination und ein weiteres pro Nutzer für alle Clients. Sie sollten Aktualisierungstokens im Langzeitspeicher speichern und sie so lange verwenden, wie sie gültig sind. Wenn Ihre Anwendung zu viele Aktualisierungstokens anfordert, kann es sein, dass diese Limits erreicht werden. In diesem Fall funktionieren ältere Aktualisierungstokens nicht mehr.
Token-Widerruf
In einigen Fällen möchte ein Nutzer möglicherweise den Zugriff einer Anwendung widerrufen. Nutzer können den Zugriff in den Kontoeinstellungen widerrufen. Weitere Informationen finden Sie im Supportdokument Drittanbieter-Websites und ‑Apps mit Zugriff auf Ihr Konto im Abschnitt „Zugriff von Websites oder Apps entfernen“.
Eine Anwendung kann den ihr gewährten Zugriff auch programmatisch widerrufen. Der programmatische Widerruf ist wichtig, wenn ein Nutzer ein Abo kündigt, eine Anwendung entfernt oder sich die von einer App benötigten API-Ressourcen erheblich geändert haben. Das bedeutet, dass ein Teil des Entfernungsprozesses eine API-Anfrage sein kann, um sicherzustellen, dass die der Anwendung zuvor gewährten Berechtigungen entfernt werden.
PHP
Rufen Sie revokeToken() auf, um ein Token programmatisch zu widerrufen:
$client->revokeToken();Python
Wenn Sie ein Token programmatisch widerrufen möchten, senden Sie eine Anfrage an https://oauth2.googleapis.com/revoke, die das Token als Parameter enthält und den Header Content-Type festlegt:
requests.post('https://oauth2.googleapis.com/revoke', params={'token': credentials.token}, headers = {'content-type': 'application/x-www-form-urlencoded'})
Ruby
Wenn Sie ein Token programmatisch widerrufen möchten, senden Sie eine HTTP-Anfrage an den Endpunkt oauth2.revoke:
uri = URI('https://oauth2.googleapis.com/revoke') response = Net::HTTP.post_form(uri, 'token' => auth_client.access_token)
Das Token kann ein Zugriffstoken oder ein Aktualisierungstoken sein. Wenn das Token ein Zugriffstoken ist und ein entsprechendes Aktualisierungstoken hat, wird das Aktualisierungstoken ebenfalls widerrufen.
Wenn der Widerruf erfolgreich verarbeitet wurde, lautet der Statuscode der Antwort 200. Bei Fehlerbedingungen wird der Statuscode 400 zusammen mit einem Fehlercode zurückgegeben.
Node.js
Wenn Sie ein Token programmatisch widerrufen möchten, senden Sie eine HTTPS-POST-Anfrage an den Endpunkt /revoke:
const https = require('https'); // Build the string for the POST request let postData = "token=" + userCredential.access_token; // Options for POST request to Google's OAuth 2.0 server to revoke a token let postOptions = { host: 'oauth2.googleapis.com', port: '443', path: '/revoke', method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': Buffer.byteLength(postData) } }; // Set up the request const postReq = https.request(postOptions, function (res) { res.setEncoding('utf8'); res.on('data', d => { console.log('Response: ' + d); }); }); postReq.on('error', error => { console.log(error) }); // Post the request with data postReq.write(postData); postReq.end();
Der Token-Parameter kann ein Zugriffstoken oder ein Aktualisierungstoken sein. Wenn das Token ein Zugriffstoken ist und ein entsprechendes Aktualisierungstoken hat, wird das Aktualisierungstoken ebenfalls widerrufen.
Wenn der Widerruf erfolgreich verarbeitet wurde, lautet der Statuscode der Antwort 200. Bei Fehlerbedingungen wird der Statuscode 400 zusammen mit einem Fehlercode zurückgegeben.
HTTP/REST
Wenn Sie ein Token programmatisch widerrufen möchten, stellt Ihre Anwendung eine Anfrage an https://oauth2.googleapis.com/revoke und fügt das Token als Parameter ein:
curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \
https://oauth2.googleapis.com/revoke?token={token}Das Token kann ein Zugriffstoken oder ein Aktualisierungstoken sein. Wenn das Token ein Zugriffstoken ist und ein entsprechendes Aktualisierungstoken hat, wird das Aktualisierungstoken ebenfalls widerrufen.
Wenn der Widerruf erfolgreich verarbeitet wurde, lautet der HTTP-Statuscode der Antwort 200. Bei Fehlerbedingungen wird ein HTTP-Statuscode 400 zusammen mit einem Fehlercode zurückgegeben.
Zeitbasierter Zugriff
Mit dem zeitbasierten Zugriff kann ein Nutzer Ihrer App für eine begrenzte Dauer Zugriff auf seine Daten gewähren, um eine Aktion auszuführen. In ausgewählten Google-Produkten ist während des Einwilligungsverfahrens ein zeitbasierter Zugriff verfügbar. Nutzer können damit den Zugriff für einen begrenzten Zeitraum gewähren. Ein Beispiel ist die Data Portability API, die eine einmalige Übertragung von Daten ermöglicht.
Wenn ein Nutzer Ihrer Anwendung zeitbasierten Zugriff gewährt, läuft das Aktualisierungstoken nach der angegebenen Dauer ab. Beachten Sie, dass Aktualisierungstokens unter bestimmten Umständen früher ungültig werden können. Weitere Informationen finden Sie in diesen Fällen. Das Feld refresh_token_expires_in, das in der Antwort auf den Austausch des Autorisierungscodes zurückgegeben wird, stellt in solchen Fällen die verbleibende Zeit bis zum Ablauf des Aktualisierungstokens dar.
Produktübergreifenden Kontoschutz implementieren
Ein weiterer Schritt, den Sie zum Schutz der Konten Ihrer Nutzer unternehmen sollten, ist die Implementierung des produktübergreifenden Kontoschutzes mithilfe des entsprechenden Google-Dienstes. Mit diesem Dienst können Sie Benachrichtigungen zu Sicherheitsereignissen abonnieren, die Ihre Anwendung über wichtige Änderungen am Nutzerkonto informieren. Anschließend können Sie die Informationen verwenden, um Maßnahmen zu ergreifen, je nachdem, wie Sie auf Ereignisse reagieren möchten.
Hier einige Beispiele für Ereignistypen, die vom produktübergreifenden Kontoschutz von Google an Ihre App gesendet werden:
-
https://schemas.openid.net/secevent/risc/event-type/sessions-revoked -
https://schemas.openid.net/secevent/oauth/event-type/token-revoked -
https://schemas.openid.net/secevent/risc/event-type/account-disabled
Weitere Informationen zur Implementierung des produktübergreifenden Kontoschutzes und eine vollständige Liste der verfügbaren Ereignisse finden Sie auf der Seite Nutzerkonten mit produktübergreifendem Kontoschutz schützen .