In diesem Dokument wird erläutert, wie Webanwendungsserver 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.
Mit OAuth 2.0 können Nutzer bestimmte Daten für eine Anwendung freigeben, 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 ihrem Google Drive zu erhalten.
Dieser OAuth 2.0-Vorgang ist speziell für die Nutzerautorisierung vorgesehen. Sie 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 statt 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-Flow Ihrer Anwendung zu verarbeiten, führt die Clientbibliothek viele Aktionen aus, die die Anwendung sonst selbst ausführen müsste. So wird beispielsweise festgelegt, wann die Anwendung gespeicherte Zugriffstokens verwenden oder aktualisieren kann und wann die Anwendung die Einwilligung neu 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
Jede Anwendung, die Google APIs aufruft, muss diese APIs in der API Consoleaktivieren.
So aktivieren Sie eine API für Ihr Projekt:
- Open the API Library in der Google API Console.
- If prompted, select a project, or create a new one.
- In der API Library finden Sie alle verfügbaren APIs nach Produktfamilie und Beliebtheit gruppiert. Wenn die API, die Sie aktivieren möchten, nicht in der Liste angezeigt wird, können Sie die Suchfunktion verwenden oder in der zugehörigen Produktfamilie auf Alle ansehen klicken.
- Wählen Sie die gewünschte API aus und klicken Sie dann auf die Schaltfläche Aktivieren.
- If prompted, enable billing.
- If prompted, read and accept the API's Terms of Service.
Anmeldedaten für die Autorisierung erstellen
Alle Anwendungen, die OAuth 2.0 für den Zugriff auf Google APIs verwenden, müssen Autorisierungsdaten haben, die die Anwendung beim OAuth 2.0-Server von Google identifizieren. In den folgenden Schritten wird erläutert, 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.
- Go to the Credentials page.
- Klicken Sie auf Anmeldedaten erstellen > OAuth-Client-ID.
- 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.
Für Tests können Sie URIs angeben, die auf den lokalen Computer verweisen, z. B.
http://localhost:8080
. In allen Beispielen in diesem Dokument wirdhttp://localhost:8080
als Weiterleitungs-URI verwendet.Wir empfehlen, die Authentifizierungsendpunkte Ihrer App so zu gestalten, dass Ihre Anwendung Autorisierungscodes nicht für andere Ressourcen auf der Seite freigibt.
Laden Sie nach dem Erstellen Ihrer Anmeldedaten die Datei client_secret.json aus der API Consoleherunter. Speichern Sie die Datei an einem sicheren Speicherort, auf den nur Ihre Anwendung zugreifen kann.
Zugriffsbereiche identifizieren
Mithilfe von Bereichen wird ermöglicht, dass eine Anwendung nur für benötigte Ressourcen den Zugriff anfordern kann, während Nutzer wiederum steuern können, wie viel Zugriff sie der Anwendung gewähren. Daher besteht möglicherweise ein umgekehrter Zusammenhang zwischen der Anzahl der angeforderten Bereiche und der Wahrscheinlichkeit, die Nutzereinwilligung einzuholen.
Bevor Sie mit der Implementierung der OAuth 2.0-Autorisierung beginnen, sollten Sie also die Bereiche ermitteln, für die Ihre Anwendung eine Zugriffsberechtigung benötigt.
Wir empfehlen außerdem, dass Ihre Anwendung den Zugriff auf Autorisierungsbereiche über einen Prozess der schrittweisen Autorisierung anfordert, bei dem Ihre Anwendung den Zugriff auf Nutzerdaten im Kontext anfordert. So können Nutzer leichter nachvollziehen, warum Ihre Anwendung den angeforderten Zugriff benötigt.
Das Dokument OAuth 2.0 API Scopes enthält eine vollständige Liste der Bereiche, die Sie für den Zugriff auf Google APIs verwenden können.
Sprachspezifische Anforderungen
Um die Codebeispiele in diesem Dokument auszuführen, benötigen Sie ein Google-Konto, Internetzugang und einen Webbrowser. Wenn Sie eine der API-Clientbibliotheken verwenden, lesen Sie auch die sprachspezifischen Anforderungen unten.
PHP
Um die PHP-Codebeispiele in diesem Dokument auszuführen, benötigen Sie Folgendes:
- PHP 8.0 oder höher mit installierter Befehlszeile und JSON-Erweiterung
- Das Composer-Tool zur Abhängigkeitsverwaltung.
-
Die Google APIs-Clientbibliothek für PHP:
composer require google/apiclient:^2.15.0
Weitere Informationen finden Sie in der Google APIs-Clientbibliothek für PHP.
Python
Um die Python-Codebeispiele in diesem Dokument auszuführen, benötigen Sie Folgendes:
- Python 3.7 oder höher
- Das Paketverwaltungstool pip
- Die Google APIs-Clientbibliothek für Python 2.0 bietet folgende Vorteile:
pip install --upgrade google-api-python-client
google-auth
,google-auth-oauthlib
undgoogle-auth-httplib2
für die Nutzerautorisierungpip install --upgrade google-auth google-auth-oauthlib google-auth-httplib2
- Das Python-Webanwendungs-Framework Flask.
pip install --upgrade flask
- Die
requests
-HTTP-Bibliothek.pip install --upgrade requests
Wenn Sie Python nicht aktualisieren können, lesen Sie die Release Notes und den zugehörigen Migrationsleitfaden für die Google API-Python-Clientbibliothek.
Ruby
Um die Ruby-Codebeispiele in diesem Dokument auszuführen, benötigen Sie Folgendes:
- Ruby 2.6 oder höher
-
Die Google Auth Library für Ruby:
gem install googleauth
-
Clientbibliotheken für Google Drive- und Google Kalender-APIs:
gem install google-apis-drive_v3 google-apis-calendar_v3
-
Das Ruby-Webanwendungs-Framework Sinatra.
gem install sinatra
Node.js
Um die Node.js-Codebeispiele in diesem Dokument auszuführen, benötigen Sie Folgendes:
- Der Wartungs-LTS, der aktive LTS oder der aktuelle Release von Node.js.
-
Der Node.js-Client für Google APIs:
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 benötigt diese Einwilligung, 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 identifiziert die erforderlichen Berechtigungen.
- Ihre Anwendung leitet den Nutzer zusammen mit der Liste der angeforderten Berechtigungen an Google weiter.
- Der Nutzer entscheidet, ob er Ihrer App die Berechtigungen erteilt.
- Ihre Anwendung ermittelt, was der Nutzer entschieden hat.
- Wenn der Nutzer die angeforderten Berechtigungen gewährt hat, ruft Ihre Anwendung Tokens ab, die zum Senden von API-Anfragen im Namen des Nutzers erforderlich sind.
Schritt 1: Autorisierungsparameter festlegen
Im ersten Schritt erstellen Sie die Autorisierungsanfrage. Mit dieser Anfrage werden Parameter festgelegt, die Ihre Anwendung identifizieren, und die Berechtigungen definiert, 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 du den Google OAuth 2.0-Endpunkt direkt aufrufst, generierst du eine URL und legst die Parameter für diese URL fest.
Auf den folgenden Tabs sind die unterstützten Autorisierungsparameter für Webanwendungsserver definiert. In den sprachspezifischen Beispielen wird auch gezeigt, wie Sie mit einer Client- oder Autorisierungsbibliothek ein Objekt konfigurieren, das diese Parameter festlegt.
PHP
Im folgenden Code-Snippet wird ein Google\Client()
-Objekt erstellt, das die Parameter in der Autorisierungsanfrage definiert.
Dieses Objekt verwendet Informationen aus Ihrer 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 gibt auch die Bereiche an, für die Ihre Anwendung die Zugriffsberechtigung anfordert, und die URL zum Authentifizierungsendpunkt Ihrer Anwendung, über den die Antwort vom OAuth 2.0-Server von Google verarbeitet wird. Schließlich werden die optionalen Parameter access_type
und include_granted_scopes
festgelegt.
Mit diesem Code wird beispielsweise Lesezugriff auf die Google Drive-Metadaten und Kalendertermine 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 google-auth-oauthlib.flow
-Modul 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 gibt auch die Bereiche an, für die Ihre Anwendung die Zugriffsberechtigung anfordert, und die URL zum Authentifizierungsendpunkt Ihrer Anwendung, über den die Antwort vom OAuth 2.0-Server von Google verarbeitet wird. Schließlich werden die optionalen Parameter access_type
und include_granted_scopes
festgelegt.
Mit diesem Code wird beispielsweise Lesezugriff auf die Google Drive-Metadaten und Kalendertermine 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, über den die Antwort vom OAuth 2.0-Server verarbeitet wird.
Mit diesem Code wird beispielsweise Lesezugriff auf die Google Drive-Metadaten und Kalendertermine 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. URLs für Autorisierungsanfragen zu generieren und Zugriffstokens auf HTTP-Anfragen anzuwenden.
Node.js
Im 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 Berechtigungen 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: Die refresh_token
wird nur bei der ersten Autorisierung zurückgegeben.
Hier finden Sie weitere Informationen dazu.
HTTP/REST
Der OAuth 2.0-Endpunkt von Google befindet sich unter https://accounts.google.com/o/oauth2/v2/auth
. Auf diesen Endpunkt kann nur über HTTPS zugegriffen werden. Unverschlüsselte HTTP-Verbindungen werden abgelehnt.
Der Google-Autorisierungsserver unterstützt die folgenden Suchstringparameter für Webanwendungsserver:
Parameter | |||||||
---|---|---|---|---|---|---|---|
client_id |
Erforderlich
Die Client-ID für Ihre Anwendung. Sie finden diesen Wert unter API Console Credentials page. |
||||||
redirect_uri |
Erforderlich
Bestimmt, wohin der API-Server den Nutzer weiterleitet, nachdem er den Autorisierungsvorgang abgeschlossen hat. Der Wert muss genau mit einem der autorisierten Weiterleitungs-URIs für den OAuth 2.0-Client übereinstimmen, den Sie in der API Console
Credentials pageIhres 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 angeben, auf die Ihre Anwendung im Namen des Nutzers zugreifen kann. Diese Werte werden auf dem Zustimmungsbildschirm angezeigt, den Google dem Nutzer präsentiert. Mithilfe von Bereichen wird ermöglicht, dass eine Anwendung nur für benötigte Ressourcen den Zugriff anfordern kann, während Nutzer wiederum steuern können, wie viel Zugriff sie der Anwendung gewähren. Daher besteht ein umgekehrter Zusammenhang zwischen der Anzahl der angeforderten Bereiche und der Wahrscheinlichkeit, die Nutzereinwilligung einzuholen. Wir empfehlen, dass Ihre Anwendung nach Möglichkeit den Zugriff auf Autorisierungsbereiche im Kontext anfordert. Wenn Sie den Zugriff auf Nutzerdaten im Kontext über eine schrittweise Autorisierung anfordern, können Nutzer leichter nachvollziehen, warum Ihre Anwendung den angeforderten Zugriff benötigt. |
||||||
access_type |
Empfohlen
Gibt an, ob Ihre Anwendung Zugriffstokens aktualisieren kann, wenn sich der Nutzer nicht im Browser befindet. 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 aufrechtzuerhalten.
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 Anfragefälschungen zu verhindern. Da Ihre |
||||||
include_granted_scopes |
Optional
Ermöglicht es Anwendungen, mithilfe der schrittweisen Autorisierung den 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 sich authentifizieren möchte, kann sie mit diesem Parameter einen Hinweis an den Google-Authentifizierungsserver senden. Der Server verwendet den Hinweis, um den Anmeldevorgang zu vereinfachen, indem er entweder das E-Mail-Feld im Anmeldeformular ausfüllt oder die entsprechende Sitzung mit mehreren Anmeldungen auswählt. Legen Sie den Parameterwert auf eine E-Mail-Adresse oder |
||||||
prompt |
Optional
Eine durch Leerzeichen getrennte Liste von Prompts, die dem Nutzer präsentiert werden sollen. Dabei 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 Nutzer zur erneuten Einwilligung auffordern. 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. Normalerweise tritt dies auf, wenn Ihre Anwendung zuerst auf die Daten des Nutzers zugreifen muss. Bei der inkrementellen Autorisierung wird dieser Schritt auch ausgeführt, wenn Ihre Anwendung zuerst auf zusätzliche Ressourcen zugreifen muss, für die sie noch 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_url
weiter:header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
Python
In diesem Beispiel wird gezeigt, wie der Nutzer mit dem Flask-Webanwendungs-Framework 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)
- Leite den Nutzer zu
auth_uri
weiter.
Node.js
-
Verwende die generierte URL
authorizationUrl
aus Schritt 1generateAuthUrl
, um Zugriff vom OAuth 2.0-Server von Google anzufordern. -
Leite den Nutzer zu
authorizationUrl
weiter.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 für eine bessere 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//oauth2.example.com/code& client_id=client_id
Nachdem du die Anfrage-URL erstellt hast, leite den Nutzer dorthin weiter.
Der OAuth 2.0-Server von Google authentifiziert den Nutzer und fordert seine Einwilligung ein, dass Ihre Anwendung auf die angeforderten Bereiche zugreifen darf. Die Antwort wird über die von Ihnen angegebene Weiterleitungs-URL an Ihre Anwendung zurückgesendet.
Schritt 3: Google fordert den Nutzer zur Einwilligung auf
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 angezeigt werden, für die mit den Autorisierungsanmeldedaten des Nutzers eine Berechtigung angefordert wird. Außerdem wird eine Zusammenfassung der zu gewährenden Zugriffsbereiche angezeigt. Der Nutzer kann dann zustimmen, 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, da sie auf die Antwort vom OAuth 2.0-Server von Google wartet, die angibt, ob Zugriff gewährt wurde. Diese Antwort wird im nächsten Schritt erläutert.
Fehler
Bei Anfragen an den OAuth 2.0-Autorisierungsendpunkt von Google werden möglicherweise nutzerorientierte Fehlermeldungen anstelle der erwarteten Authentifizierungs- und Autorisierungsabläufe angezeigt. Im Folgenden finden Sie häufige Fehlercodes und empfohlene Lösungen.
admin_policy_enforced
Das Google-Konto kann aufgrund der Richtlinien des Google Workspace-Administrators einen oder mehrere der angeforderten Bereiche nicht autorisieren. Im Hilfeartikel für Google Workspace-Administratoren Zugriff externer und interner Apps auf Google Workspace-Daten verwalten finden Sie weitere Informationen dazu, wie ein Administrator den Zugriff auf alle oder vertrauliche und eingeschränkte Bereiche einschränken kann, bis der Zugriff Ihrer OAuth-Client-ID ausdrücklich gewährt wird.
disallowed_useragent
Der Autorisierungsendpunkt wird in einem eingebetteten User-Agent angezeigt, der gemäß den OAuth 2.0-Richtlinien von Google nicht zulässig ist.
Android
Android-Entwickler sehen diese Fehlermeldung möglicherweise, wenn sie Autorisierungsanfragen in android.webkit.WebView
öffnen.
Entwickler sollten stattdessen Android-Bibliotheken wie Google Log-in für Android oder AppAuth für Android der OpenID Foundation verwenden.
Webentwickler können diesen Fehler erhalten, wenn eine Android-App einen allgemeinen Weblink in einem eingebetteten User-Agent öffnet und ein Nutzer von Ihrer Website zum OAuth 2.0-Autorisierungsendpunkt von Google gelangt. Entwickler sollten zulassen, dass allgemeine Links im Standard-Link-Handler des Betriebssystems geöffnet werden. Dazu gehören sowohl Android App Link-Handler als auch die Standard-Browser-App. Die Android Custom Tabs-Bibliothek ist ebenfalls eine unterstützte Option.
iOS
iOS- und macOS-Entwickler können diesen Fehler erhalten, wenn sie Autorisierungsanfragen in WKWebView
öffnen.
Entwickler sollten stattdessen iOS-Bibliotheken wie Google Log-in für iOS oder AppAuth für iOS der OpenID Foundation verwenden.
Webentwickler können diesen Fehler erhalten, 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 gelangt. 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
Das OAuth-Client-Secret ist falsch. Prüfen Sie die OAuth-Clientkonfiguration, einschließlich der für diese Anfrage verwendeten Client-ID und des Secrets.
invalid_grant
Wenn Sie ein Zugriffstoken aktualisieren oder die inkrementelle Autorisierung verwenden, ist das Token möglicherweise abgelaufen oder ungültig. Authentifizieren Sie den Nutzer noch einmal und bitten Sie um seine Einwilligung, um neue Tokens zu erhalten. Wenn dieser Fehler weiterhin auftritt, prüfen Sie, ob Ihre Anwendung richtig konfiguriert ist und Sie die richtigen Tokens und Parameter in Ihrer Anfrage verwenden. Andernfalls wurde das Nutzerkonto möglicherweise gelöscht oder deaktiviert.
redirect_uri_mismatch
Die in der Autorisierungsanfrage übergebene redirect_uri
stimmt nicht mit einem autorisierten Weiterleitungs-URI für die OAuth-Client-ID überein. Überprüfen Sie die autorisierten Weiterleitungs-URIs in Google API Console Credentials page.
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. Weitere Informationen zur Aktualisierung Ihrer Integration finden Sie im Migrationsleitfaden.
invalid_request
Bei Ihrer Anfrage ist ein Fehler aufgetreten. Das kann verschiedene Gründe haben:
- Die Anfrage war nicht richtig formatiert.
- In der Anfrage fehlen erforderliche Parameter.
- Die Anfrage verwendet eine Autorisierungsmethode, die von Google nicht unterstützt wird. Prüfen, ob für die 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 anhand der in der Anfrage angegebenen 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 unten dargestellt:
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. Dabei wird schreibgeschützter Zugriff angefordert, um Metadaten für Dateien in Google Drive aufzurufen, und schreibgeschützter Zugriff, um Ihre Google Kalender-Termine aufzurufen:
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//oauth2.example.com/code& client_id=client_id
Nach Abschluss des OAuth 2.0-Ablaufs sollten Sie zu http://localhost/oauth2callback
weitergeleitet werden. Dies führt jedoch wahrscheinlich zu einem 404 NOT FOUND
-Fehler, es sei denn, auf Ihrem lokalen Computer wird eine Datei an dieser Adresse bereitgestellt. Im nächsten Schritt erfahren Sie mehr über die Informationen, die im URI zurückgegeben werden, wenn der Nutzer zu Ihrer Anwendung zurückgeleitet wird.
Schritt 5: Autorisierungscode gegen Aktualisierungs- und Zugriffstoken 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 Autorisierungsserverantwort zu überprü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 the session. # ACTION ITEM for developers: # Store user's access and refresh tokens in your data store if # incorporating this code into your real app. credentials = flow.credentials flask.session['credentials'] = { 'token': credentials.token, 'refresh_token': credentials.refresh_token, 'token_uri': credentials.token_uri, 'client_id': credentials.client_id, 'client_secret': credentials.client_secret, 'granted_scopes': credentials.granted_scopes}
Ruby
Verwende auf deiner Callback-Seite die googleauth
-Bibliothek, um die Antwort des Autorisierungsservers zu überprüfen. Verwende die authorizer.handle_auth_callback_deferred
-Methode, um den Autorisierungscode zu speichern und zur URL zurückzuleiten, über die die Autorisierung ursprünglich angefordert wurde. Dadurch wird der Austausch des Codes verschoben, 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 einzutauschen:
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 du einen Autorisierungscode gegen ein Zugriffstoken eintauschen möchtest, rufe den Endpunkt https://oauth2.googleapis.com/token
auf und lege die folgenden Parameter fest:
Felder | |
---|---|
client_id |
Die Client-ID, die von der API Console Credentials pageabgerufen wurde. |
client_secret |
Der Clientschlüssel, der von der API Console Credentials pageabgerufen wurde. |
code |
Der Autorisierungscode, der von der ursprünglichen Anfrage zurückgegeben wurde. |
grant_type |
Gemäß der OAuth 2.0-Spezifikation muss der Wert dieses Felds auf authorization_code gesetzt werden. |
redirect_uri |
Einer der Weiterleitungs-URIs, die für Ihr Projekt in der API Console
Credentials page für die angegebene client_id aufgeführt sind. |
Das folgende Snippet zeigt eine Beispielanfrage:
POST /token HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7& client_id=your_client_id& client_secret=your_client_secret& redirect_uri=https%3A//oauth2.example.com/code& grant_type=authorization_code
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
festgelegt hat.
Die Antwort umfasst die folgenden Felder:
Felder | |
---|---|
access_token |
Das Token, das Ihre Anwendung sendet, um eine Google API-Anfrage zu autorisieren. |
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.
Dieses Feld ist nur dann in dieser Antwort enthalten, wenn Sie den Parameter access_type in der ursprünglichen Anfrage an den Autorisierungsserver von Google auf offline gesetzt haben.
|
scope |
Die Zugriffsbereiche, die durch das access_token gewährt werden, als Liste von durch Leerzeichen getrennten, groß- und kleinschreibungssensitiven Strings. |
token_type |
Der Typ des zurückgegebenen Tokens. Derzeit ist der Wert dieses Felds immer auf Bearer festgelegt. |
Das folgende Snippet zeigt eine Beispielantwort:
{ "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 eintauschen, erhalten Sie möglicherweise anstelle der erwarteten Antwort den folgenden Fehler. Im Folgenden finden Sie häufige Fehlercodes und empfohlene Lösungen.
invalid_grant
Der angegebene Autorisierungscode ist ungültig oder hat ein falsches Format. Fordern Sie einen neuen Code an, indem Sie den OAuth-Vorgang neu starten, um den Nutzer noch einmal um seine Einwilligung zu bitten.
Schritt 6: Prüfen, welche Berechtigungen Nutzer gewährt haben
Wenn Sie mehrere Bereiche gleichzeitig anfordern, gewähren Nutzer möglicherweise nicht alle Bereiche, die Ihre App anfordert. Ihre App sollte immer prüfen, welche Bereiche vom Nutzer gewährt wurden, und bei einer Ablehnung von Bereichen die entsprechenden Funktionen deaktivieren. Weitere Informationen finden Sie unter Detaillierte Berechtigungen verwalten.
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 die Property granted_scopes
, eine Liste der Berechtigungen, die der Nutzer Ihrer App gewährt hat.
credentials = flow.credentials flask.session['credentials'] = { 'token': credentials.token, 'refresh_token': credentials.refresh_token, 'token_uri': credentials.token_uri, 'client_id': credentials.client_id, 'client_secret': credentials.client_secret, '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 du mehrere Bereiche gleichzeitig anforderst, prüfe, welche Bereiche über die Eigenschaft scope
des credentials
-Objekts 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 du mehrere Bereiche gleichzeitig anforderst, prüfe, welche Bereiche über die Eigenschaft scope
des tokens
-Objekts 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
Ob der Nutzer Ihrer Anwendung Zugriff auf einen bestimmten Bereich gewährt hat, sehen Sie im Feld scope
in der Antwort des Zugriffstokens. Die Zugriffsbereiche, die durch das access_token gewährt werden, als Liste von durch Leerzeichen getrennten Strings, die zwischen Groß- und Kleinschreibung unterscheiden.
In der folgenden Beispielantwort für ein Zugriffstoken ist beispielsweise zu sehen, dass der Nutzer Ihrer Anwendung Lesezugriff auf 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
So rufen Sie mit dem Zugriffstoken Google APIs auf:
- Wenn Sie ein Zugriffstoken auf ein neues
Google\Client
-Objekt anwenden möchten, 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 der API, die Sie aufrufen möchten, ein autorisiertes
Google\Client
-Objekt zur Verfügung stellen. So rufen Sie beispielsweise die Drive API auf:$drive = new Google\Service\Drive($client);
- Stellen Sie Anfragen an den API-Dienst über die
vom Dienstobjekt bereitgestellte Benutzeroberfläche.
So listen Sie beispielsweise die Dateien im Google Drive des authentifizierten Nutzers auf:
$files = $drive->files->listFiles(array());
Python
Nachdem Ihre Anwendung ein Zugriffstoken abgerufen hat, kann sie damit API-Anfragen im Namen eines bestimmten Nutzer- oder Dienstkontos autorisieren. Verwenden Sie die nutzerspezifischen Autorisierungsanmeldedaten, um ein Dienstobjekt für die API zu erstellen, die Sie aufrufen möchten, und verwenden Sie dann dieses Objekt, um autorisierte API-Anfragen zu senden.
- Erstellen Sie ein Dienstobjekt für die API, die Sie aufrufen möchten. Sie erstellen ein Dienstobjekt, indem Sie die
build
-Methode dergoogleapiclient.discovery
-Bibliothek mit dem Namen und der Version der API und den Nutzeranmeldedaten aufrufen: So rufen Sie beispielsweise Version 3 der Drive API auf:from googleapiclient.discovery import build drive = build('drive', 'v2', credentials=credentials)
- Stellen Sie Anfragen an den API-Dienst über die vom Dienstobjekt bereitgestellte Benutzeroberfläche.
So listen Sie beispielsweise die Dateien im Google Drive des authentifizierten Nutzers auf:
files = drive.files().list().execute()
Ruby
Nachdem ein Zugriffstoken abgerufen wurde, kann Ihre Anwendung dieses Token verwenden, um im Namen eines bestimmten Nutzer- oder Dienstkontos API-Anfragen zu senden. Verwenden Sie die nutzerspezifischen Autorisierungsanmeldedaten, um ein Dienstobjekt für die API zu erstellen, die Sie aufrufen möchten, und verwenden Sie dann dieses Objekt, um autorisierte API-Anfragen zu senden.
- Erstellen Sie ein Dienstobjekt für die API, die Sie aufrufen möchten.
So rufen Sie beispielsweise Version 3 der Drive API auf:
drive = Google::Apis::DriveV3::DriveService.new
- Legen Sie die Anmeldedaten für den Dienst fest:
drive.authorization = credentials
- Stellen Sie Anfragen an den API-Dienst über die vom Dienstobjekt bereitgestellte Benutzeroberfläche.
So listen Sie beispielsweise die Dateien im Google Drive des authentifizierten Nutzers auf:
files = drive.list_files
Alternativ kann die Autorisierung pro Methode bereitgestellt werden, 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 für das OAuth2
-Objekt festgelegt haben, können Sie damit Google APIs aufrufen. Ihre Anwendung kann dieses Token verwenden, um API-Anfragen im Namen eines bestimmten Nutzer- 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 im Drive 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 eine Google API aufrufen, sofern die von der API erforderlichen Zugriffsbereiche gewährt wurden. Dazu fügen Sie das Zugriffstoken in eine Anfrage an die API ein, indem Sie entweder einen access_token
-Abfrageparameter oder einen Authorization
-HTTP-Header-Bearer
-Wert angeben. Wenn möglich, ist der HTTP-Header vorzuziehen, da Suchstrings in Serverprotokollen in der Regel sichtbar sind. In den meisten Fällen können Sie mit einer Clientbibliothek Aufrufe von Google APIs einrichten, z. B. beim Aufrufen der Drive Files API.
Im OAuth 2.0 Playground können Sie alle Google APIs ausprobieren und sich ihre Bereiche ansehen.
Beispiele für HTTP-GET
Ein Aufruf des Endpunkts
drive.files
(Drive Files API) mit dem HTTP-Header Authorization: Bearer
könnte so aussehen: Sie müssen Ihr eigenes Zugriffstoken angeben:
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 Befehlszeilenanwendung curl
testen. Hier ein Beispiel, in dem die HTTP-Header-Option verwendet wird (bevorzugt):
curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files
Alternativ können Sie auch die Option „Abfragestringparameter“ verwenden:
curl https://www.googleapis.com/drive/v2/files?access_token=access_token
Vollständiges Beispiel
Im folgenden Beispiel wird eine JSON-Liste der Dateien im Google Drive eines Nutzers ausgegeben, nachdem sich der Nutzer authentifiziert und der Anwendung die Berechtigung zum Zugriff auf seine Drive-Metadaten erteilt hat.
PHP
So führen Sie das Beispiel aus:
- Fügen Sie in der Datei API Consoledie URL des lokalen Computers zur Liste der Weiterleitungs-URLs hinzu, z. B.
http://localhost:8080
. - Erstellen Sie ein neues Verzeichnis und wechseln Sie zu diesem Verzeichnis. 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.php
undoauth2callback.php
mit folgendem Inhalt: - Führen Sie das Beispiel mit dem integrierten Test-Webserver von PHP 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. Dort 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 fünf Links angezeigt werden:
- Drive API aufrufen:Dieser Link verweist auf eine Seite, auf der versucht wird, eine Beispiel-API-Anfrage auszuführen, wenn Nutzer die Berechtigung erteilt haben. Falls erforderlich, startet er den Autorisierungsvorgang. Bei Erfolg wird auf der Seite die API-Antwort angezeigt.
- Mock-Seite zum Aufrufen der Kalender API:Dieser Link verweist auf eine Mock-Seite, auf der versucht wird, eine Beispielanfrage an die Kalender API auszuführen, wenn Nutzer die Berechtigung erteilt haben. Falls erforderlich, startet er den Autorisierungsvorgang. Bei Erfolg wird auf der Seite die API-Antwort angezeigt.
- Autorisierungsablauf direkt testen:Dieser Link verweist auf eine Seite, auf der versucht wird, 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 Autorisierungsanmeldedaten gelöscht, die in der Flask-Sitzung gespeichert sind. So sehen Sie, was passiert, wenn ein Nutzer, der Ihrer App bereits eine Berechtigung erteilt hat, versucht, in einer neuen Sitzung eine API-Anfrage auszuführen. Außerdem sehen Sie die API-Antwort, die Ihre App erhalten würde, wenn ein Nutzer die Berechtigungen für Ihre App widerrufen hat und Ihre App trotzdem versucht, eine Anfrage mit einem widerrufenen Zugriffstoken zu autorisieren.
# -*- coding: utf-8 -*- import os import flask 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 credentials from the session. credentials = google.oauth2.credentials.Credentials( **flask.session['credentials']) 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. # ACTION ITEM: In a production app, you likely want to save these # credentials in a persistent database instead. flask.session['credentials'] = credentials_to_dict(credentials) return flask.jsonify(**files) else: # User didn't authorize read-only Drive activity permission. # Update UX and application accordingly 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.') credentials = google.oauth2.credentials.Credentials( **flask.session['credentials']) 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: 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, 'token_uri': credentials.token_uri, 'client_id': credentials.client_id, 'client_secret': credentials.client_secret, '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="/test">Test an API request</a></td>' + '<td>Submit an API request and see a formatted JSON response. ' + ' Go through the authorization flow if there are no stored ' + ' credentials for the user.</td></tr>' + '<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="/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="/test">test the ' + ' API request</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 Datei API Consoledie URL des lokalen Computers der Liste der Weiterleitungs-URLs hinzu, z. B.
http://localhost
. - Sie müssen einen LTS-Support-Release, einen aktiven LTS-Release oder den aktuellen Release von Node.js installiert haben.
-
Erstellen Sie ein neues Verzeichnis und wechseln Sie zu diesem Verzeichnis. Beispiel:
mkdir ~/nodejs-oauth2-example cd ~/nodejs-oauth2-example
-
Google API-Clientbibliothek für Node.js mit npm installieren:
npm install googleapis
-
Erstellen Sie die Dateien
main.js
mit folgendem Inhalt: -
Beispiel ausführen:
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 wird das Flask-Framework und die Requests-Bibliothek verwendet, um den OAuth 2.0-Webablauf zu veranschaulichen. Wir empfehlen für diesen Ablauf die Verwendung der Google API-Clientbibliothek für Python. 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 zu helfen, ihre Anwendungen zu schützen. Ihre Weiterleitungs-URIs müssen diesen Regeln entsprechen. Die Definitionen für „domain“, „host“, „path“, „query“, „scheme“ und „userinfo“ finden Sie unten in RFC 3986 Abschnitt 3.
Validierungsregeln | |
---|---|
Schema |
Für Weiterleitungs-URIs muss das HTTPS-Schema verwendet werden, nicht nur HTTP. Localhost-URIs (einschließlich localhost-IP-Adressen-URIs) sind von dieser Regel ausgenommen. |
Moderator:in |
Hosts dürfen keine Roh-IP-Adressen sein. Localhost-IP-Adressen sind von dieser Regel ausgenommen. |
Domain |
“googleusercontent.com” sein.goo.gl ) enthalten, es sei denn, die Domain gehört der App. Wenn eine App mit einer Domain eines URL-Kürzungsdiensts auf diese Domain weiterleitet, muss der URI für die Weiterleitung entweder “/google-callback/” im Pfad enthalten oder auf “/google-callback” enden. |
Userinfo |
Weiterleitungs-URIs dürfen die Unterkomponente „userinfo“ nicht enthalten. |
Pfad |
Weiterleitungs-URIs dürfen keine Pfadweiterleitung (auch als Verzeichnisrückwärtssuche bezeichnet) enthalten, die durch ein |
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 gekennzeichnet sind. Aus Gründen der Nutzerfreundlichkeit sollten Sie die Autorisierung für Ressourcen immer dann anfordern, wenn Sie sie benötigen. Dazu unterstützt der Autorisierungsserver von Google die inkrementelle Autorisierung. Mit dieser Funktion können Sie nach Bedarf Zugriffsbereiche anfordern. Wenn der Nutzer die Berechtigung für den neuen Bereich gewährt, 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 Musiktitel samplen und Mixe erstellen können, benötigt beispielsweise bei der Anmeldung möglicherweise nur sehr wenige Ressourcen, vielleicht nur den Namen der Person, die sich anmeldet. Zum Speichern eines fertigen Mixes ist jedoch Zugriff auf sein Google Drive erforderlich. Die meisten Nutzer würden es für selbstverständlich halten, wenn sie nur dann um Zugriff auf ihr Google Drive-Konto gebeten würden, 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 grundlegende Anmeldung durchzuführen, und dann später bei der ersten Anfrage den Bereich https://www.googleapis.com/auth/drive.file
, um einen Mix zu speichern.
Wenn Sie die inkrementelle Autorisierung implementieren möchten, führen Sie den normalen Ablauf zum Anfordern eines Zugriffstokens aus. Achten Sie jedoch darauf, dass die Autorisierungsanfrage zuvor gewährte Bereiche enthält. So müssen Sie in Ihrer App nicht mehrere Zugriffstokens verwalten.
Für ein Zugriffstoken, das über eine inkrementelle Autorisierung abgerufen wurde, gelten die folgenden Regeln:
- Das Token kann verwendet werden, um auf Ressourcen zuzugreifen, die den Bereichen entsprechen, die in die neue kombinierte Autorisierung übernommen 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 jeden der 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 Berechtigungen 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 einen weiteren Bereich für dieselbe Anwendung gewährt hat, 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: Autorisierungsparameter festlegen und in der Beispiel-HTTP/REST-Weiterleitungs-URL in Schritt 2: Zum OAuth 2.0-Server von Google weiterleiten wird die inkrementelle Autorisierung verwendet. Die folgenden Codebeispiele enthalten auch den Code, den Sie hinzufügen müssen, um die inkrementelle Autorisierung zu verwenden.
PHP
$client->setIncludeGrantedScopes(true);
Python
Legen Sie in Python das Keyword-Argument 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//oauth2.example.com/code& 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 eine Berechtigung zu bitten, auch wenn der Nutzer nicht anwesend ist, wenn Sie den Offlinezugriff auf die mit dem Token verknüpften Bereiche angefordert haben.
- Wenn Sie eine Google API-Clientbibliothek verwenden, wird das Zugriffstoken vom Clientobjekt nach Bedarf aktualisiert, sofern Sie dieses Objekt für den Offlinezugriff konfigurieren.
- Wenn Sie keine Clientbibliothek verwenden, müssen Sie den
access_type
-HTTP-Suchparameter aufoffline
setzen, 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 du einen Autorisierungscode gegen ein Zugriffstoken eintauschst. Wenn das Zugriffstoken abläuft (oder jederzeit), können Sie ein Aktualisierungstoken verwenden, um ein neues Zugriffstoken abzurufen.
Das Anfordern des Offlinezugriffs ist eine Voraussetzung für jede Anwendung, die auf eine Google API zugreifen muss, wenn der Nutzer nicht vorhanden ist. Beispielsweise muss eine App, die Sicherungsdienste ausführt oder Aktionen zu festgelegten 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 Autorisierungsvorgangs Aktualisierungstokens. Aktualisierungstokens werden in der Regel nicht in clientseitigen (JavaScript-)Webanwendungen 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 weiterhin den API-Client verwenden, um im Namen des Nutzers auf Google APIs zuzugreifen, wenn er offline ist. Das Clientobjekt aktualisiert das Zugriffstoken nach Bedarf.
Python
Legen Sie in Python das Keyword-Argument access_type
auf offline
fest, damit Sie das Zugriffstoken aktualisieren können, 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 weiterhin den API-Client verwenden, um im Namen des Nutzers auf Google APIs zuzugreifen, wenn er 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 weiterhin den API-Client verwenden, um im Namen des Nutzers auf Google APIs zuzugreifen, wenn er 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 weiterhin den API-Client verwenden, um im Namen des Nutzers auf Google APIs zuzugreifen, wenn er offline ist. Das Clientobjekt aktualisiert das Zugriffstoken nach Bedarf.
Zugriffstokens laufen ab. Diese Bibliothek verwendet automatisch ein Aktualisierungstoken, um ein neues Zugriffstoken abzurufen, wenn das aktuelle Token bald abläuft. Mit dem Ereignis „tokens“ können Sie ganz einfach dafür sorgen, dass immer die neuesten Tokens gespeichert werden:
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 Tokens-Ereignis tritt nur bei der ersten Autorisierung auf. Du musst access_type
auf offline
gesetzt haben, wenn du die generateAuthUrl
-Methode aufrufst, 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 noch einmal 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
Um ein Zugriffstoken zu aktualisieren, sendet Ihre Anwendung eine HTTPS-POST
-Anfrage an den Autorisierungsserver (https://oauth2.googleapis.com/token
) von Google, die die folgenden Parameter enthält:
Felder | |
---|---|
client_id |
Die Client-ID, die von der API Consoleabgerufen wurde. |
client_secret |
Der Clientschlüssel, der von der API Consoleabgerufen wurde. |
grant_type |
Gemäß der OAuth 2.0-Spezifikation muss der Wert dieses Felds auf refresh_token gesetzt werden. |
refresh_token |
Das Aktualisierungstoken, das vom Autorisierungscode-Austausch zurückgegeben wird. |
Das folgende Snippet zeigt eine Beispielanfrage:
POST /token HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded client_id=your_client_id& client_secret=your_client_secret& refresh_token=refresh_token& grant_type=refresh_token
Solange der Nutzer den der Anwendung gewährten Zugriff nicht widerrufen hat, gibt der Tokenserver ein JSON-Objekt mit einem neuen Zugriffstoken zurück. Das folgende Snippet zeigt eine Beispielantwort:
{ "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" }
Die Anzahl der ausgestellten Aktualisierungstokens ist begrenzt. Es gibt ein Limit pro Kombination aus Kunde und Nutzer sowie ein Limit pro Nutzer für alle Kunden. Sie sollten Aktualisierungstokens im Langzeitspeicher speichern und so lange verwenden, wie sie gültig sind. Wenn Ihre Anwendung zu viele Aktualisierungstokens anfordert, kann es zu diesen Limits kommen. In diesem Fall funktionieren ältere Aktualisierungstokens nicht mehr.
Token widerrufen
In einigen Fällen möchte ein Nutzer den einer Anwendung erteilten Zugriff widerrufen. Nutzer können den Zugriff in den Kontoeinstellungen widerrufen. Weitere Informationen finden Sie im Hilfeartikel Websites und Apps von Drittanbietern mit Zugriff auf Ihr Konto im Abschnitt Zugriff auf Websites oder Apps entfernen.
Es ist auch möglich, dass eine Anwendung den ihr gewährten Zugriff programmatisch widerruft. Der programmatische Widerruf ist wichtig, wenn ein Nutzer sein Abo kündigt, eine App entfernt oder sich die von einer App benötigten API-Ressourcen erheblich geändert haben. Mit anderen Worten: Ein Teil des Entfernungsvorgangs kann eine API-Anfrage umfassen, um sicherzustellen, dass die zuvor der Anwendung erteilten Berechtigungen entfernt werden.
PHP
Wenn du ein Token programmatisch widerrufen möchtest, ruf revokeToken()
auf:
$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 Zugriffs- oder Aktualisierungstoken sein. Wenn es sich bei dem Token um ein Zugriffstoken handelt und es ein entsprechendes Aktualisierungstoken hat, wird auch das Aktualisierungstoken widerrufen.
Wenn der Widerruf erfolgreich verarbeitet wurde, lautet der Statuscode der Antwort 200
. Bei Fehlern wird der Statuscode 400
zusammen mit einem Fehlercode zurückgegeben.
Node.js
Wenn du ein Token programmatisch widerrufen möchtest, sende 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 Tokenparameter kann ein Zugriffs- oder Aktualisierungstoken sein. Wenn es sich bei dem Token um ein Zugriffstoken handelt und es ein entsprechendes Aktualisierungstoken hat, wird auch das Aktualisierungstoken widerrufen.
Wenn der Widerruf erfolgreich verarbeitet wurde, lautet der Statuscode der Antwort 200
. Bei Fehlern wird der Statuscode 400
zusammen mit einem Fehlercode zurückgegeben.
HTTP/REST
Wenn Sie ein Token programmatisch widerrufen möchten, sendet Ihre Anwendung eine Anfrage an https://oauth2.googleapis.com/revoke
und fügt das Token als Parameter hinzu:
curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \ https://oauth2.googleapis.com/revoke?token={token}
Das Token kann ein Zugriffs- oder Aktualisierungstoken sein. Wenn es sich bei dem Token um ein Zugriffstoken handelt und es ein entsprechendes Aktualisierungstoken hat, wird auch das Aktualisierungstoken widerrufen.
Wenn der Widerruf erfolgreich verarbeitet wurde, lautet der HTTP-Statuscode der Antwort 200
. Bei Fehlerbedingungen wird der HTTP-Statuscode 400
zusammen mit einem Fehlercode zurückgegeben.
Produktübergreifenden Kontoschutz implementieren
Sie sollten außerdem den Kontoübergreifenden Schutz implementieren, indem Sie den Kontoübergreifenden Schutzdienst von Google verwenden. Mit diesem Dienst können Sie Benachrichtigungen zu Sicherheitsereignissen abonnieren, die Ihre Anwendung über wichtige Änderungen am Nutzerkonto informieren. Je nachdem, wie Sie auf Ereignisse reagieren möchten, können Sie dann Maßnahmen ergreifen.
Beispiele für Ereignistypen, die vom geräteübergreifenden Schutzdienst 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
Auf der Seite Nutzerkonten mit dem produktübergreifenden Kontoschutz schützen finden Sie weitere Informationen zur Implementierung des produktübergreifenden Kontoschutzes und eine vollständige Liste der verfügbaren Ereignisse.