Korzystanie z protokołu OAuth 2.0 w aplikacjach serwerowych

Ten dokument wyjaśnia, w jaki sposób aplikacje serwera WWW korzystają z Google API Client Libraries lub punktów końcowych Google OAuth 2.0 do implementacji autoryzacji OAuth 2.0 na potrzeby dostępu do interfejsów API Google.

Protokół OAuth 2.0 umożliwia użytkownikom udostępnianie określonych danych aplikacji przy jednoczesnym zachowaniu poufności nazw, haseł i innych informacji. Aplikacja może na przykład używać protokołu OAuth 2.0, aby uzyskiwać od użytkowników uprawnienia do przechowywania plików na ich Dyskach Google.

Ten proces OAuth 2.0 służy konkretnie do autoryzacji użytkowników. Została zaprojektowana z myślą o aplikacjach, które mogą przechowywać poufne informacje i utrzymywać stan aplikacji. Prawidłowo autoryzowana aplikacja serwera WWW może uzyskać dostęp do interfejsu API, gdy użytkownik korzysta z aplikacji lub po jej opuszczeniu.

Aplikacje serwera WWW często używają kont usługi do autoryzowania żądań do interfejsu API, zwłaszcza gdy wywołują interfejsy Cloud APIs, aby uzyskać dostęp do danych opartych na projekcie, a nie do danych konkretnych użytkowników. Aplikacje serwera WWW mogą używać kont usługi w połączeniu z autoryzacją użytkownika.

Biblioteki klienta

Przykłady w różnych językach na tej stronie korzystają z Google API Client Libraries do wdrożenia autoryzacji OAuth 2.0. Aby uruchomić przykładowy kod, musisz najpierw zainstalować bibliotekę klienta dla swojego języka.

Gdy do obsługi procesu OAuth 2.0 w swojej aplikacji używasz biblioteki klienta interfejsu API Google, biblioteka klienta wykonuje wiele działań, które w innym przypadku musiałaby obsługiwać samodzielnie. Określa na przykład, kiedy aplikacja może używać lub odświeżać zapisanych tokenów dostępu oraz kiedy musi uzyskać zgodę użytkownika. Biblioteka klienta generuje też prawidłowe przekierowania i pomaga wdrożyć moduły obsługi przekierowań, które wymieniają kody autoryzacji na tokeny dostępu.

Biblioteki klienta interfejsów API Google dla aplikacji po stronie serwera są dostępne w tych językach:

Wymagania wstępne

Włącz interfejsy API w projekcie

Każda aplikacja wywołująca interfejsy API Google musi włączyć te interfejsy w zadaniu API Console.

Aby włączyć interfejs API w projekcie:

  1. Open the API Library w: Google API Console.
  2. If prompted, select a project, or create a new one.
  3. Lista API Library zawiera listę wszystkich dostępnych interfejsów API uporządkowanych według rodziny usług i popularności. Jeśli interfejsu API, który chcesz włączyć, nie ma na liście, wyszukaj go za pomocą wyszukiwarki lub kliknij Wyświetl wszystkie w rodzinie usług, do której należy.
  4. Wybierz interfejs API, który chcesz włączyć, a następnie kliknij przycisk Włącz.
  5. If prompted, enable billing.
  6. If prompted, read and accept the API's Terms of Service.

Tworzenie danych uwierzytelniających

Każda aplikacja korzystająca z protokołu OAuth 2.0 do uzyskiwania dostępu do interfejsów API Google musi mieć dane uwierzytelniające, które identyfikują aplikację na serwerze Google OAuth 2.0. Poniższe kroki wyjaśniają, jak utworzyć dane logowania do projektu. Aplikacje mogą następnie używać tych danych logowania, aby uzyskiwać dostęp do interfejsów API włączonych w tym projekcie.

  1. Go to the Credentials page.
  2. Kliknij Utwórz dane logowania > Identyfikator klienta OAuth.
  3. Wybierz typ aplikacji Aplikacja internetowa.
  4. Wypełnij formularz i kliknij Utwórz. Aplikacje korzystające z języków i platform, takich jak PHP, Java, Python, Ruby i .NET, muszą określać autoryzowane identyfikatory URI przekierowania. Identyfikatory URI przekierowania to punkty końcowe, do których serwer OAuth 2.0 może wysyłać odpowiedzi. Te punkty końcowe muszą być zgodne z regułami weryfikacji Google.

    Na potrzeby testowania możesz podać identyfikatory URI odnoszące się do komputera lokalnego, na przykład http://localhost:8080. Mając to na uwadze, pamiętaj, że we wszystkich przykładach w tym dokumencie identyfikator URI przekierowania to http://localhost:8080.

    Zalecamy zaprojektowanie punktów końcowych uwierzytelniania aplikacji w taki sposób, aby aplikacja nie ujawniała kodów autoryzacji innym zasobom na stronie.

Gdy utworzysz dane logowania, pobierz plik client_secret.json z API Console. Bezpiecznie zapisz plik w lokalizacji, do której ma dostęp tylko Twoja aplikacja.

Zidentyfikuj zakresy dostępu

Zakresy umożliwiają aplikacji dostęp tylko do potrzebnych zasobów, a jednocześnie pozwalają użytkownikom kontrolować zakres dostępu, który przyznają Twojej aplikacji. Dlatego może występować odwrotna zależność między liczbą żądanych zakresów a prawdopodobieństwem uzyskania zgody użytkownika.

Przed wdrożeniem autoryzacji OAuth 2.0 zalecamy wskazanie zakresów, do których aplikacja będzie potrzebować uprawnień.

Zalecamy też, aby aplikacja prosiła o dostęp do zakresów autoryzacji przy użyciu procesu przyrostowej autoryzacji, w ramach którego aplikacja prosi o dostęp do danych użytkownika w kontekście. Ta sprawdzona metoda ułatwia użytkownikom zrozumienie, dlaczego aplikacja potrzebuje dostępu, o który prosi.

Dokument Zakresy interfejsów API OAuth 2.0 zawiera pełną listę zakresów, które mogą być używane w celu uzyskania dostępu do interfejsów API Google.

Wymagania związane z określonym językiem

Aby uruchomić dowolny przykładowy kod z tego dokumentu, potrzebujesz konta Google, dostępu do internetu i przeglądarki. Jeśli używasz jednej z bibliotek klienta interfejsu API, zapoznaj się również z wymaganiami dotyczącymi określonego języka poniżej.

PHP

Aby uruchomić przykładowy kod PHP w tym dokumencie, potrzebujesz:

  • PHP w wersji 5.6 lub nowszej z zainstalowanym interfejsem wiersza poleceń i rozszerzeniem JSON.
  • narzędzie do zarządzania zależnościami Composer.
  • Biblioteka klienta interfejsów API Google do języka PHP:

    composer require google/apiclient:^2.10

Python

Aby uruchomić przykładowy kod Pythona w tym dokumencie, musisz mieć:

  • Python 2.6 lub nowszy
  • narzędzie do zarządzania pakietami pip,
  • Biblioteka klienta interfejsów API Google do języka Python:
    pip install --upgrade google-api-python-client
  • google-auth, google-auth-oauthlib i google-auth-httplib2 do autoryzacji użytkownika.
    pip install --upgrade google-auth google-auth-oauthlib google-auth-httplib2
  • Platforma aplikacji internetowej Flask Python.
    pip install --upgrade flask
  • Biblioteka HTTP requests.
    pip install --upgrade requests

Ruby

Aby uruchomić przykładowy kod Ruby w tym dokumencie, musisz mieć:

  • Ruby 2.6 lub nowsza
  • Biblioteka Google Auth Library w Ruby:

    gem install googleauth
  • Platforma aplikacji internetowych Sinatra Ruby.

    gem install sinatra

Node.js

Aby uruchomić przykładowy kod w Node.js w tym dokumencie, potrzebujesz:

  • Kanał LTS konserwacji, aktywny kanał LTS lub bieżąca wersja Node.js.
  • Klient Node.js interfejsów API Google:

    npm install googleapis

HTTP/REST

Nie musisz instalować żadnych bibliotek, aby mieć możliwość bezpośredniego wywoływania punktów końcowych OAuth 2.0.

Uzyskiwanie tokenów dostępu OAuth 2.0

Poniższe kroki pokazują, jak Twoja aplikacja współpracuje z serwerem OAuth 2.0 Google, aby uzyskać zgodę użytkownika na wykonanie żądania do interfejsu API w jego imieniu. Twoja aplikacja musi mieć taką zgodę, zanim będzie mogła wykonywać żądania do interfejsu Google API wymagające autoryzacji użytkownika.

Poniższa lista zawiera krótkie podsumowanie tych czynności:

  1. Aplikacja określa potrzebne uprawnienia.
  2. Aplikacja przekierowuje użytkownika do Google wraz z listą wymaganych uprawnień.
  3. To użytkownik decyduje, czy przyznać te uprawnienia aplikacji.
  4. Aplikacja poznaje decyzję użytkownika.
  5. Jeśli użytkownik przyznał wymagane uprawnienia, aplikacja pobiera tokeny potrzebne do wysyłania żądań do interfejsu API w imieniu użytkownika.

Krok 1. Ustaw parametry autoryzacji

Najpierw utwórz żądanie autoryzacji. Żądanie to ustawia parametry identyfikujące aplikację i definiują uprawnienia, o które użytkownik zostanie poproszony o przyznanie aplikacji.

  • Jeśli używasz biblioteki klienta Google do uwierzytelniania i autoryzacji OAuth 2.0, możesz utworzyć i skonfigurować obiekt definiujący te parametry.
  • Jeśli wywołujesz bezpośrednio punkt końcowy Google OAuth 2.0, wygeneruj adres URL i ustaw parametry tego adresu URL.

Poniższe karty określają obsługiwane parametry autoryzacji dla aplikacji serwera WWW. Przykłady w poszczególnych językach pokazują też, jak użyć biblioteki klienta lub biblioteki autoryzacji do skonfigurowania obiektu ustawiającego te parametry.

PHP

Poniższy fragment kodu tworzy obiekt Google\Client(), który określa parametry w żądaniu autoryzacji.

Ten obiekt używa informacji z Twojego pliku client_secret.json do identyfikacji Twojej aplikacji. Więcej informacji o tym pliku znajdziesz w artykule o tworzeniu danych uwierzytelniających. Ten obiekt identyfikuje zakresy, do których aplikacja żąda uprawnień dostępu, oraz adres URL punktu końcowego uwierzytelniania aplikacji, który będzie obsługiwać odpowiedź z serwera Google OAuth 2.0. Na koniec kod ustawia opcjonalne parametry access_type i include_granted_scopes.

Na przykład ten kod prosi o dostęp tylko do odczytu w trybie offline do Dysku Google użytkownika:

$client = new Google\Client();
$client->setAuthConfig('client_secret.json');
$client->addScope(Google\Service\Drive::DRIVE_METADATA_READONLY);
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');
// 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');
// Using "consent" will prompt the user for consent
$client->setPrompt('consent');
$client->setIncludeGrantedScopes(true);   // incremental auth

Prośba zawiera te informacje:

Parametry
client_id Wymagany

Identyfikator klienta aplikacji. Tę wartość znajdziesz w API Console Credentials page.

W PHP wywołaj funkcję setAuthConfig, aby wczytać dane logowania do autoryzacji z pliku client_secret.json.

$client = new Google\Client();
$client->setAuthConfig('client_secret.json');
redirect_uri Wymagany

Określa, dokąd serwer interfejsu API przekierowuje użytkownika po zakończeniu procesu autoryzacji. Wartość musi dokładnie odpowiadać jednemu z autoryzowanych identyfikatorów URI przekierowania dla klienta OAuth 2.0, które zostały skonfigurowane w API Console Credentials pageTwojego klienta. Jeśli ta wartość nie jest zgodna z autoryzowanym identyfikatorem URI przekierowania dla podanego identyfikatora client_id, pojawi się błąd redirect_uri_mismatch.

Pamiętaj, że schemat http lub https, wielkość liter i ukośnik na końcu („/”) muszą być zgodne.

Aby ustawić tę wartość w PHP, wywołaj funkcję setRedirectUri. Pamiętaj, że musisz podać prawidłowy identyfikator URI przekierowania dla podanego elementu client_id.

$client->setRedirectUri('https://oauth2.example.com/code');
scope Wymagany

Lista rozdzielonych spacjami zakresów określających zasoby, do których aplikacja może uzyskiwać dostęp w imieniu użytkownika. Wartości te mają wpływ na ekran zgody wyświetlany przez Google użytkownikowi.

Zakresy umożliwiają aplikacji dostęp tylko do potrzebnych zasobów, a jednocześnie pozwalają użytkownikom kontrolować zakres dostępu, który przyznają Twojej aplikacji. Dlatego istnieje odwrotna zależność między liczbą żądanych zakresów a prawdopodobieństwem uzyskania zgody użytkownika.

Aby ustawić tę wartość w PHP, wywołaj funkcję addScope:

$client->addScope(Google\Service\Drive::DRIVE_METADATA_READONLY);

Zalecamy, aby aplikacja prosiła o dostęp do zakresów autoryzacji w kontekście, gdy jest to możliwe. Wysyłając prośbę o dostęp do danych użytkownika w kontekście, korzystając z autoryzacji przyrostowej, ułatwiasz użytkownikom zrozumienie, dlaczego aplikacja potrzebuje dostępu, o który prosi.

access_type Zalecane

Wskazuje, czy aplikacja może odświeżać tokeny dostępu, gdy użytkownika nie ma w przeglądarce. Prawidłowe wartości parametru to online (wartość domyślna) i offline.

Ustaw wartość offline, jeśli aplikacja musi odświeżać tokeny dostępu, gdy użytkownika nie ma w przeglądarce. To metoda odświeżania tokenów dostępu opisana w dalszej części tego dokumentu. Ta wartość instruuje serwer autoryzacji Google, że ma zwrócić token odświeżania oraz token dostępu, gdy Twoja aplikacja po raz pierwszy wymienia kod autoryzacji na tokeny.

Aby ustawić tę wartość w PHP, wywołaj funkcję setAccessType:

$client->setAccessType('offline');
state Zalecane

Określa dowolną wartość ciągu znaków, której aplikacja używa do zachowania stanu między żądaniem autoryzacji a odpowiedzią serwera autoryzacji. Serwer zwraca dokładną wartość, którą wysyłasz jako parę name=value w komponencie zapytania adresu URL (?) obiektu redirect_uri, gdy użytkownik wyrazi zgodę na dostęp aplikacji lub go odrzuci.

Parametru tego można używać do różnych celów, np. do kierowania użytkownika do odpowiedniego zasobu w aplikacji, wysyłania liczb jednorazowych i łagodzenia skutków fałszowania żądań pochodzących z innych witryn. Ponieważ redirect_uri można odgadnąć, użycie wartości state może zwiększyć pewność, że połączenie przychodzące jest wynikiem żądania uwierzytelniania. Jeśli generujesz losowy ciąg znaków lub zakodujesz skrót pliku cookie bądź inną wartość, która przechwytuje stan klienta, możesz zweryfikować odpowiedź, aby dodatkowo upewnić się, że żądanie i odpowiedź pochodzą z tej samej przeglądarki. Zabezpiecza to przed atakami, takimi jak fałszowanie żądań z innych witryn. Przykład sposobu tworzenia i potwierdzania tokena state znajdziesz w dokumentacji OpenID Connect.

Aby ustawić tę wartość w PHP, wywołaj funkcję setState:

$client->setState($sample_passthrough_value);
include_granted_scopes Opcjonalny

Umożliwia aplikacjom korzystanie z przyrostowej autoryzacji w celu zażądania dostępu do dodatkowych zakresów w kontekście. Jeśli ustawisz wartość tego parametru na true i żądanie autoryzacji zostanie przyznane, nowy token dostępu będzie też obejmować wszystkie zakresy, do których użytkownik przyznał dostęp aplikacji. Przykłady znajdziesz w sekcji o przyrostowej autoryzacji.

Aby ustawić tę wartość w PHP, wywołaj funkcję setIncludeGrantedScopes:

$client->setIncludeGrantedScopes(true);
login_hint Opcjonalny

Jeśli aplikacja wie, który użytkownik próbuje się uwierzytelnić, może użyć tego parametru, aby wyświetlić wskazówkę dla serwera uwierzytelniania Google. Serwer korzysta z podpowiedzi, aby uprościć proces logowania, wstępnie wypełniając pole adresu e-mail w formularzu logowania lub wybierając odpowiednią sesję wielokrotnego logowania.

Ustaw wartość parametru na adres e-mail lub identyfikator sub, który odpowiada identyfikatorowi Google użytkownika.

Aby ustawić tę wartość w PHP, wywołaj funkcję setLoginHint:

$client->setLoginHint('None');
prompt Opcjonalny

Lista rozdzielanych spacjami promptów dla użytkownika (z uwzględnieniem wielkości liter). Jeśli nie określisz tego parametru, użytkownik będzie pytany tylko wtedy, gdy Twój projekt po raz pierwszy poprosi o dostęp. Więcej informacji znajdziesz w sekcji Proszenie o ponowne wyrażenie zgody.

Aby ustawić tę wartość w PHP, wywołaj funkcję setPrompt:

$client->setPrompt('consent');

Możliwe wartości to:

none Nie wyświetlaj żadnych ekranów uwierzytelniania ani zgody. Nie można podawać innych wartości.
consent Wyświetlaj użytkownikowi prośbę o zgodę na wykorzystanie danych.
select_account Proś użytkownika o wybranie konta.

Python

Poniższy fragment kodu używa modułu google-auth-oauthlib.flow do utworzenia żądania autoryzacji.

Kod tworzy obiekt Flow, który identyfikuje aplikację na podstawie informacji z pliku client_secret.json pobranego po utworzeniu danych logowania do autoryzacji. Ten obiekt identyfikuje również zakresy, do których aplikacja żąda uprawnień dostępu, oraz adres URL punktu końcowego uwierzytelniania aplikacji, który będzie obsługiwać odpowiedź z serwera Google OAuth 2.0. Na koniec kod ustawia opcjonalne parametry access_type i include_granted_scopes.

Na przykład ten kod prosi o dostęp tylko do odczytu w trybie offline do Dysku Google użytkownika:

import google.oauth2.credentials
import google_auth_oauthlib.flow

# Use the client_secret.json file to identify the application requesting
# authorization. The client ID (from that file) and access scopes are required.
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
    'client_secret.json',
    scopes=['https://www.googleapis.com/auth/drive.metadata.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.
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(
    # 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')

Prośba zawiera te informacje:

Parametry
client_id Wymagany

Identyfikator klienta aplikacji. Tę wartość znajdziesz w API Console Credentials page.

W Pythonie wywołaj metodę from_client_secrets_file, aby pobrać identyfikator klienta z pliku client_secret.json. (Możesz też użyć metody from_client_config, która przekazuje konfigurację klienta w takiej postaci, w jakiej była pierwotnie w pliku z tajnymi kluczami klienta, ale nie ma dostępu do samego pliku).

flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
    'client_secret.json',
    scopes=['https://www.googleapis.com/auth/drive.metadata.readonly'])
redirect_uri Wymagany

Określa, dokąd serwer interfejsu API przekierowuje użytkownika po zakończeniu procesu autoryzacji. Wartość musi dokładnie odpowiadać jednemu z autoryzowanych identyfikatorów URI przekierowania dla klienta OAuth 2.0, które zostały skonfigurowane w API Console Credentials pageTwojego klienta. Jeśli ta wartość nie jest zgodna z autoryzowanym identyfikatorem URI przekierowania dla podanego identyfikatora client_id, pojawi się błąd redirect_uri_mismatch.

Pamiętaj, że schemat http lub https, wielkość liter i ukośnik na końcu („/”) muszą być zgodne.

Aby ustawić tę wartość w Pythonie, ustaw właściwość redirect_uri obiektu flow:

flow.redirect_uri = 'https://oauth2.example.com/code'
scope Wymagany

Lista zakresów identyfikujących zasoby, do których aplikacja może uzyskiwać dostęp w imieniu użytkownika. Wartości te mają wpływ na ekran zgody wyświetlany przez Google użytkownikowi.

Zakresy umożliwiają aplikacji dostęp tylko do potrzebnych zasobów, a jednocześnie pozwalają użytkownikom kontrolować zakres dostępu, który przyznają Twojej aplikacji. Dlatego istnieje odwrotna zależność między liczbą żądanych zakresów a prawdopodobieństwem uzyskania zgody użytkownika.

W Pythonie użyj tej samej metody, co do konfigurowania client_id w celu określenia listy zakresów.

flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
    'client_secret.json',
    scopes=['https://www.googleapis.com/auth/drive.metadata.readonly'])

Zalecamy, aby aplikacja prosiła o dostęp do zakresów autoryzacji w kontekście, gdy jest to możliwe. Wysyłając prośbę o dostęp do danych użytkownika w kontekście, korzystając z autoryzacji przyrostowej, ułatwiasz użytkownikom zrozumienie, dlaczego aplikacja potrzebuje dostępu, o który prosi.

access_type Zalecane

Wskazuje, czy aplikacja może odświeżać tokeny dostępu, gdy użytkownika nie ma w przeglądarce. Prawidłowe wartości parametru to online (wartość domyślna) i offline.

Ustaw wartość offline, jeśli aplikacja musi odświeżać tokeny dostępu, gdy użytkownika nie ma w przeglądarce. To metoda odświeżania tokenów dostępu opisana w dalszej części tego dokumentu. Ta wartość instruuje serwer autoryzacji Google, że ma zwrócić token odświeżania oraz token dostępu, gdy Twoja aplikacja po raz pierwszy wymienia kod autoryzacji na tokeny.

W Pythonie ustaw parametr access_type, określając access_type jako argument słowa kluczowego podczas wywoływania metody flow.authorization_url:

authorization_url, state = flow.authorization_url(
    access_type='offline',
    include_granted_scopes='true')
state Zalecane

Określa dowolną wartość ciągu znaków, której aplikacja używa do zachowania stanu między żądaniem autoryzacji a odpowiedzią serwera autoryzacji. Serwer zwraca dokładną wartość, którą wysyłasz jako parę name=value w komponencie zapytania adresu URL (?) obiektu redirect_uri, gdy użytkownik wyrazi zgodę na dostęp aplikacji lub go odrzuci.

Parametru tego można używać do różnych celów, np. do kierowania użytkownika do odpowiedniego zasobu w aplikacji, wysyłania liczb jednorazowych i łagodzenia skutków fałszowania żądań pochodzących z innych witryn. Ponieważ redirect_uri można odgadnąć, użycie wartości state może zwiększyć pewność, że połączenie przychodzące jest wynikiem żądania uwierzytelniania. Jeśli generujesz losowy ciąg znaków lub zakodujesz skrót pliku cookie bądź inną wartość, która przechwytuje stan klienta, możesz zweryfikować odpowiedź, aby dodatkowo upewnić się, że żądanie i odpowiedź pochodzą z tej samej przeglądarki. Zabezpiecza to przed atakami, takimi jak fałszowanie żądań z innych witryn. Przykład sposobu tworzenia i potwierdzania tokena state znajdziesz w dokumentacji OpenID Connect.

W Pythonie ustaw parametr state, określając state jako argument słowa kluczowego podczas wywoływania metody flow.authorization_url:

authorization_url, state = flow.authorization_url(
    access_type='offline',
    state=sample_passthrough_value,
    include_granted_scopes='true')
include_granted_scopes Opcjonalny

Umożliwia aplikacjom korzystanie z przyrostowej autoryzacji w celu zażądania dostępu do dodatkowych zakresów w kontekście. Jeśli ustawisz wartość tego parametru na true i żądanie autoryzacji zostanie przyznane, nowy token dostępu będzie też obejmować wszystkie zakresy, do których użytkownik przyznał dostęp aplikacji. Przykłady znajdziesz w sekcji o przyrostowej autoryzacji.

W Pythonie ustaw parametr include_granted_scopes, określając include_granted_scopes jako argument słowa kluczowego podczas wywoływania metody flow.authorization_url:

authorization_url, state = flow.authorization_url(
    access_type='offline',
    include_granted_scopes='true')
login_hint Opcjonalny

Jeśli aplikacja wie, który użytkownik próbuje się uwierzytelnić, może użyć tego parametru, aby wyświetlić wskazówkę dla serwera uwierzytelniania Google. Serwer korzysta z podpowiedzi, aby uprościć proces logowania, wstępnie wypełniając pole adresu e-mail w formularzu logowania lub wybierając odpowiednią sesję wielokrotnego logowania.

Ustaw wartość parametru na adres e-mail lub identyfikator sub, który odpowiada identyfikatorowi Google użytkownika.

W Pythonie ustaw parametr login_hint, określając login_hint jako argument słowa kluczowego podczas wywoływania metody flow.authorization_url:

authorization_url, state = flow.authorization_url(
    access_type='offline',
    login_hint='None',
    include_granted_scopes='true')
prompt Opcjonalny

Lista rozdzielanych spacjami promptów dla użytkownika (z uwzględnieniem wielkości liter). Jeśli nie określisz tego parametru, użytkownik będzie pytany tylko wtedy, gdy Twój projekt po raz pierwszy poprosi o dostęp. Więcej informacji znajdziesz w sekcji Proszenie o ponowne wyrażenie zgody.

W Pythonie ustaw parametr prompt, określając prompt jako argument słowa kluczowego podczas wywoływania metody flow.authorization_url:

authorization_url, state = flow.authorization_url(
      access_type='offline',
      prompt='consent',
      include_granted_scopes='true')

Możliwe wartości to:

none Nie wyświetlaj żadnych ekranów uwierzytelniania ani zgody. Nie można podawać innych wartości.
consent Wyświetlaj użytkownikowi prośbę o zgodę na wykorzystanie danych.
select_account Proś użytkownika o wybranie konta.

Ruby

Użyj utworzonego przez siebie pliku client_secrets.json, aby skonfigurować obiekt klienta w aplikacji. Podczas konfigurowania obiektu klienta określasz zakresy, do których aplikacja ma mieć dostęp, oraz adres URL punktu końcowego uwierzytelniania, który będzie obsługiwać odpowiedź z serwera OAuth 2.0.

Na przykład ten kod prosi o dostęp tylko do odczytu w trybie offline do Dysku Google użytkownika:

require 'google/apis/drive_v3'
require "googleauth"
require 'googleauth/stores/redis_token_store'

client_id = Google::Auth::ClientId.from_file('/path/to/client_secret.json')
scope = 'https://www.googleapis.com/auth/drive.metadata.readonly'
token_store = Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new)
authorizer = Google::Auth::WebUserAuthorizer.new(client_id, scope, token_store, '/oauth2callback')

Your application uses the client object to perform OAuth 2.0 operations, such as generating authorization request URLs and applying access tokens to HTTP requests.

Node.js

The code snippet below creates a google.auth.OAuth2 object, which defines the parameters in the authorization request.

That object uses information from your client_secret.json file to identify your application. To ask for permissions from a user to retrieve an access token, you redirect them to a consent page. To create a consent page URL:

const {google} = require('googleapis');

/**
 * 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 read-only Drive activity.
const scopes = [
  'https://www.googleapis.com/auth/drive.metadata.readonly'
];

// Generate a url that asks permissions for the Drive activity 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
});

Ważna uwaga: refresh_token jest zwracany tylko podczas pierwszej autoryzacji. Więcej informacji znajdziesz tutaj.

HTTP/REST

Punkt końcowy Google OAuth 2.0 znajduje się pod adresem https://accounts.google.com/o/oauth2/v2/auth. Ten punkt końcowy jest dostępny tylko przez HTTPS. Zwykłe połączenia HTTP są odrzucane.

Serwer autoryzacji Google obsługuje te parametry ciągu zapytania dla aplikacji serwera WWW:

Parametry
client_id Wymagany

Identyfikator klienta aplikacji. Tę wartość znajdziesz w API Console Credentials page.

redirect_uri Wymagany

Określa, dokąd serwer interfejsu API przekierowuje użytkownika po zakończeniu procesu autoryzacji. Wartość musi dokładnie odpowiadać jednemu z autoryzowanych identyfikatorów URI przekierowania dla klienta OAuth 2.0, które zostały skonfigurowane w API Console Credentials pageTwojego klienta. Jeśli ta wartość nie jest zgodna z autoryzowanym identyfikatorem URI przekierowania dla podanego identyfikatora client_id, pojawi się błąd redirect_uri_mismatch.

Pamiętaj, że schemat http lub https, wielkość liter i ukośnik na końcu („/”) muszą być zgodne.

response_type Wymagany

Określa, czy punkt końcowy Google OAuth 2.0 zwraca kod autoryzacji.

Ustaw wartość tego parametru na code w przypadku aplikacji serwera WWW.

scope Wymagany

Lista rozdzielonych spacjami zakresów określających zasoby, do których aplikacja może uzyskiwać dostęp w imieniu użytkownika. Wartości te mają wpływ na ekran zgody wyświetlany przez Google użytkownikowi.

Zakresy umożliwiają aplikacji dostęp tylko do potrzebnych zasobów, a jednocześnie pozwalają użytkownikom kontrolować zakres dostępu, który przyznają Twojej aplikacji. Dlatego istnieje odwrotna zależność między liczbą żądanych zakresów a prawdopodobieństwem uzyskania zgody użytkownika.

Zalecamy, aby aplikacja prosiła o dostęp do zakresów autoryzacji w kontekście, gdy jest to możliwe. Wysyłając prośbę o dostęp do danych użytkownika w kontekście, korzystając z autoryzacji przyrostowej, ułatwiasz użytkownikom zrozumienie, dlaczego aplikacja potrzebuje dostępu, o który prosi.

access_type Zalecane

Wskazuje, czy aplikacja może odświeżać tokeny dostępu, gdy użytkownika nie ma w przeglądarce. Prawidłowe wartości parametru to online (wartość domyślna) i offline.

Ustaw wartość offline, jeśli aplikacja musi odświeżać tokeny dostępu, gdy użytkownika nie ma w przeglądarce. To metoda odświeżania tokenów dostępu opisana w dalszej części tego dokumentu. Ta wartość instruuje serwer autoryzacji Google, że ma zwrócić token odświeżania oraz token dostępu, gdy Twoja aplikacja po raz pierwszy wymienia kod autoryzacji na tokeny.

state Zalecane

Określa dowolną wartość ciągu znaków, której aplikacja używa do zachowania stanu między żądaniem autoryzacji a odpowiedzią serwera autoryzacji. Serwer zwraca dokładną wartość, którą wysyłasz jako parę name=value w komponencie zapytania adresu URL (?) obiektu redirect_uri, gdy użytkownik wyrazi zgodę na dostęp aplikacji lub go odrzuci.

Parametru tego można używać do różnych celów, np. do kierowania użytkownika do odpowiedniego zasobu w aplikacji, wysyłania liczb jednorazowych i łagodzenia skutków fałszowania żądań pochodzących z innych witryn. Ponieważ redirect_uri można odgadnąć, użycie wartości state może zwiększyć pewność, że połączenie przychodzące jest wynikiem żądania uwierzytelniania. Jeśli generujesz losowy ciąg znaków lub zakodujesz skrót pliku cookie bądź inną wartość, która przechwytuje stan klienta, możesz zweryfikować odpowiedź, aby dodatkowo upewnić się, że żądanie i odpowiedź pochodzą z tej samej przeglądarki. Zabezpiecza to przed atakami, takimi jak fałszowanie żądań z innych witryn. Przykład sposobu tworzenia i potwierdzania tokena state znajdziesz w dokumentacji OpenID Connect.

include_granted_scopes Opcjonalny

Umożliwia aplikacjom korzystanie z przyrostowej autoryzacji w celu zażądania dostępu do dodatkowych zakresów w kontekście. Jeśli ustawisz wartość tego parametru na true i żądanie autoryzacji zostanie przyznane, nowy token dostępu będzie też obejmować wszystkie zakresy, do których użytkownik przyznał dostęp aplikacji. Przykłady znajdziesz w sekcji o przyrostowej autoryzacji.

login_hint Opcjonalny

Jeśli aplikacja wie, który użytkownik próbuje się uwierzytelnić, może użyć tego parametru, aby wyświetlić wskazówkę dla serwera uwierzytelniania Google. Serwer korzysta z podpowiedzi, aby uprościć proces logowania, wstępnie wypełniając pole adresu e-mail w formularzu logowania lub wybierając odpowiednią sesję wielokrotnego logowania.

Ustaw wartość parametru na adres e-mail lub identyfikator sub, który odpowiada identyfikatorowi Google użytkownika.

prompt Opcjonalny

Lista rozdzielanych spacjami promptów dla użytkownika (z uwzględnieniem wielkości liter). Jeśli nie określisz tego parametru, użytkownik będzie pytany tylko wtedy, gdy Twój projekt po raz pierwszy poprosi o dostęp. Więcej informacji znajdziesz w sekcji Proszenie o ponowne wyrażenie zgody.

Możliwe wartości to:

none Nie wyświetlaj żadnych ekranów uwierzytelniania ani zgody. Nie można podawać innych wartości.
consent Wyświetlaj użytkownikowi prośbę o zgodę na wykorzystanie danych.
select_account Proś użytkownika o wybranie konta.

Krok 2. Przekieruj na serwer OAuth 2.0 Google

Przekieruj użytkownika na serwer Google OAuth 2.0, aby zainicjować proces uwierzytelniania i autoryzacji. Zwykle dzieje się tak, gdy aplikacja po raz pierwszy musi uzyskać dostęp do danych użytkownika. W przypadku autoryzacji przyrostowej ten krok występuje również wtedy, gdy aplikacja po raz pierwszy potrzebuje dostępu do dodatkowych zasobów, do których nie ma jeszcze uprawnień dostępu.

PHP

  1. Wygeneruj URL, aby poprosić o dostęp z serwera OAuth 2.0 Google:
    $auth_url = $client->createAuthUrl();
  2. Przekieruj użytkownika do witryny $auth_url:
    header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));

Python

Ten przykład pokazuje, jak przekierować użytkownika pod adres URL autoryzacji za pomocą platformy aplikacji internetowych Flask:

return flask.redirect(authorization_url)

Ruby

  1. Wygeneruj URL, aby poprosić o dostęp z serwera OAuth 2.0 Google:
    auth_uri = authorizer.get_authorization_url(login_hint: user_id, request: request)
  2. Przekieruj użytkownika do witryny auth_uri.

Node.js

  1. Użyj wygenerowanego adresu URL authorizationUrl w kroku 1 generateAuthUrl, aby poprosić o dostęp z serwera Google OAuth 2.0.
  2. Przekieruj użytkownika do witryny authorizationUrl.
    res.writeHead(301, { "Location": authorizationUrl });

HTTP/REST

Sample redirect to Google's authorization server

An example URL is shown below, with line breaks and spaces for readability.

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.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

Po utworzeniu adresu URL żądania przekieruj na niego użytkownika.

Serwer Google OAuth 2.0 uwierzytelnia użytkownika i uzyskuje od niego zgodę na dostęp aplikacji do żądanych zakresów. Odpowiedź jest wysyłana z powrotem do aplikacji przy użyciu podanego przekierowania.

Krok 3. Google prosi użytkownika o zgodę na wykorzystanie danych

W tym kroku użytkownik decyduje, czy przyznać aplikacji wymagany dostęp. Na tym etapie Google wyświetla okno zgody z nazwą Twojej aplikacji i usług interfejsu Google API, do których prosi o dostęp za pomocą danych uwierzytelniających użytkownika, a także podsumowanie zakresów do przyznania dostępu. Użytkownik może następnie wyrazić zgodę na przyznanie dostępu do co najmniej 1 zakresu żądanego przez Twoją aplikację lub odrzucić żądanie.

Na tym etapie Twoja aplikacja nie musi nic robić, ponieważ czeka na odpowiedź serwera OAuth 2.0 Google z informacją, czy został przyznany dostęp. Odpowiedź wyjaśnimy w następnym kroku.

Błędy

Żądania wysyłane do punktu końcowego autoryzacji OAuth 2.0 Google mogą wyświetlać komunikaty o błędach dla użytkowników zamiast oczekiwanych przepływów uwierzytelniania i autoryzacji. Poniżej znajdziesz typowe kody błędów i sugerowane sposoby ich rozwiązania.

admin_policy_enforced

Na koncie Google nie można autoryzować co najmniej jednego żądanego zakresu ze względu na zasady administratora Google Workspace. Przeczytaj artykuł pomocy dla administratorów Google Workspace Określanie, które aplikacje innych firm i aplikacje wewnętrzne mają dostęp do danych Google Workspace, aby dowiedzieć się więcej o tym, jak administrator może ograniczać dostęp do wszystkich zakresów lub zakresów wrażliwych i zakresów z ograniczeniami do czasu wyraźnego przyznania dostępu Twojemu identyfikatorowi klienta OAuth.

disallowed_useragent

Punkt końcowy autoryzacji jest wyświetlany wewnątrz osadzonego klienta użytkownika, który jest niedozwolony przez zasady Google OAuth 2.0.

Android

Deweloperzy aplikacji na Androida mogą napotkać ten komunikat o błędzie podczas otwierania żądań autoryzacji w zadaniu android.webkit.WebView. Deweloperzy powinni używać bibliotek Androida takich jak Google Sign-In for Android czy AppAuth for Android fundacji OpenID.

Programiści stron internetowych mogą napotkać ten błąd, gdy aplikacja na Androida otwiera ogólny link internetowy w umieszczonym kliencie użytkownika, a użytkownik przechodzi z Twojej witryny do punktu końcowego autoryzacji OAuth 2.0 Google. Deweloperzy powinni zezwolić na otwieranie ogólnych linków w domyślnym module obsługi linków systemu operacyjnego, który obejmuje moduły obsługi linków do aplikacji na Androida lub domyślną aplikację przeglądarki. Obsługiwana jest też biblioteka kart niestandardowych na Androida.

iOS

Deweloperzy korzystający z systemów iOS i macOS mogą napotkać ten błąd podczas otwierania żądań autoryzacji w WKWebView. Deweloperzy powinni używać bibliotek iOS takich jak Google Sign-In for iOS czy AppAuth for iOS od OpenID Foundation.

Programiści stron internetowych mogą napotkać ten błąd, gdy aplikacja na iOS lub macOS otworzy ogólny link internetowy w umieszczonym kliencie użytkownika, a użytkownik przejdzie z Twojej witryny do punktu końcowego autoryzacji OAuth 2.0 Google. Deweloperzy powinni zezwolić na otwieranie ogólnych linków w domyślnym module obsługi linków systemu operacyjnego, który obejmuje moduły obsługi linków uniwersalnych lub domyślną aplikację przeglądarki. Obsługiwaną opcją jest też biblioteka SFSafariViewController.

org_internal

Identyfikator klienta OAuth w żądaniu jest częścią projektu ograniczającego dostęp do kont Google w konkretnej organizacji Google Cloud. Więcej informacji o tej konfiguracji znajdziesz w sekcji Typ użytkownika artykułu pomocy „Konfigurowanie ekranu zgody OAuth”.

invalid_client

Klucz klienta OAuth jest nieprawidłowy. Sprawdź konfigurację klienta OAuth, w tym identyfikator klienta i tajny klucz użyty w żądaniu.

invalid_grant

Podczas odświeżania tokena dostępu lub przy użyciu autoryzacji przyrostowej token mógł wygasnąć lub został unieważniony. Uwierzytelnij użytkownika ponownie i poproś o zgodę użytkownika na uzyskanie nowych tokenów. Jeśli ten błąd nadal się pojawia, sprawdź, czy aplikacja została skonfigurowana prawidłowo i czy w żądaniu używasz prawidłowych tokenów i parametrów. W przeciwnym razie konto użytkownika mogło zostać usunięte lub wyłączone.

redirect_uri_mismatch

Wartość redirect_uri przekazana w żądaniu autoryzacji nie pasuje do autoryzowanego identyfikatora URI przekierowania dla identyfikatora klienta OAuth. Sprawdź autoryzowane identyfikatory URI przekierowania w: Google API Console Credentials page.

Parametr redirect_uri może odnosić się do poza zakresem protokołu OAuth (OOB), który został wycofany i nie jest już obsługiwany. Informacje na temat aktualizacji integracji znajdziesz w przewodniku po migracji.

invalid_request

Coś poszło nie tak z przesłaną przez Ciebie prośbą. Istnieje kilka możliwych przyczyn tej sytuacji:

  • Żądanie nie było poprawnie sformatowane
  • W żądaniu brakowało wymaganych parametrów
  • Żądanie używa metody autoryzacji, której Google nie obsługuje. Sprawdź, czy integracja OAuth używa zalecanej metody integracji

Krok 4. Przetwórz odpowiedź serwera OAuth 2.0

Serwer OAuth 2.0 odpowiada na żądanie dostępu aplikacji, używając adresu URL podanego w żądaniu.

Jeśli użytkownik zatwierdzi prośbę o dostęp, odpowiedź będzie zawierała kod autoryzacji. Jeśli użytkownik nie zaakceptuje prośby, odpowiedź zawiera komunikat o błędzie. Kod autoryzacji lub komunikat o błędzie zwrócony na serwer WWW jest widoczny w ciągu zapytania, jak pokazano poniżej:

Odpowiedź dotycząca błędu:

https://oauth2.example.com/auth?error=access_denied

Odpowiedź dotycząca kodu autoryzacji:

https://oauth2.example.com/auth?code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7

Przykładowa odpowiedź serwera OAuth 2.0

Możesz przetestować ten proces, klikając poniższy przykładowy URL, który prosi o dostęp tylko do odczytu do wyświetlania metadanych plików na Dysku Google:

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.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

Po zakończeniu procesu dotyczącego protokołu OAuth 2.0 nastąpi przekierowanie do strony http://localhost/oauth2callback, co prawdopodobnie spowoduje wystąpienie błędu 404 NOT FOUND, chyba że komputer lokalny udostępnia plik pod tym adresem. Następny krok zawiera więcej informacji o informacjach zwracanych w identyfikatorze URI po przekierowaniu użytkownika z powrotem do aplikacji.

Krok 5. Wymień kod autoryzacji dla tokenów odświeżania i dostępu

Gdy serwer WWW otrzyma kod autoryzacji, może wymienić go na token dostępu.

PHP

Aby wymienić kod autoryzacji na token dostępu, użyj metody authenticate:

$client->authenticate($_GET['code']);

Token dostępu możesz pobrać przy użyciu metody getAccessToken:

$access_token = $client->getAccessToken();

Python

Na stronie wywołania zwrotnego sprawdź odpowiedź serwera autoryzacji za pomocą biblioteki google-auth. Następnie użyj metody flow.fetch_token, aby wymienić kod autoryzacji w odpowiedzi na token dostępu:

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,
    'scopes': credentials.scopes}

Ruby

Na stronie wywołania zwrotnego sprawdź odpowiedź serwera autoryzacji, używając biblioteki googleauth. Użyj metody authorizer.handle_auth_callback_deferred, aby zapisać kod autoryzacji i przekierować z powrotem na adres URL, który pierwotnie zażądał autoryzacji. Powoduje to odroczenie wymiany kodu przez tymczasowe przechowywanie wyników w sesji użytkownika.

  target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request)
  redirect target_url

Node.js

Aby wymienić kod autoryzacji na token dostępu, użyj metody getToken:

const url = require('url');

// Receive the callback from Google's OAuth 2.0 server.
if (req.url.startsWith('/oauth2callback')) {
  // Handle the OAuth 2.0 server response
  let q = url.parse(req.url, true).query;

  // Get access and refresh tokens (if access_type is offline)
  let { tokens } = await oauth2Client.getToken(q.code);
  oauth2Client.setCredentials(tokens);
}

HTTP/REST

Aby wymienić kod autoryzacji na token dostępu, wywołaj punkt końcowy https://oauth2.googleapis.com/token i ustaw te parametry:

Pola
client_id Identyfikator klienta uzyskany z API Console Credentials page.
client_secret Tajny klucz klienta uzyskany z API Console Credentials page.
code Kod autoryzacji zwrócony w wyniku początkowego żądania.
grant_type Zgodnie ze specyfikacją OAuth 2.0 wartość tego pola musi być ustawiona na authorization_code.
redirect_uri Jeden z identyfikatorów URI przekierowania wymieniony w tabeli API Console Credentials page dla wybranego zasobu (client_id).

Ten fragment kodu zawiera przykładowe żądanie:

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 odpowiada na to żądanie, zwracając obiekt JSON zawierający token dostępu o ograniczonym czasie ważności i token odświeżania. Token odświeżania jest zwracany tylko wtedy, gdy w pierwszym żądaniu do serwera autoryzacji Google Twoja aplikacja ustawi parametr access_type na offline.

Odpowiedź zawiera te pola:

Pola
access_token Token wysyłany przez aplikację w celu autoryzacji żądania do interfejsu API Google.
expires_in Pozostały czas życia tokena dostępu w sekundach.
refresh_token Token, za pomocą którego możesz uzyskać nowy token dostępu. Tokeny odświeżania są ważne do chwili, gdy użytkownik unieważni dostęp. To pole występuje w tej odpowiedzi tylko wtedy, gdy w pierwszym żądaniu wysyłanym do serwera autoryzacji Google ustawisz parametr access_type na offline.
scope Zakresy dostępu przyznane przez zasadę access_token w postaci listy ciągów znaków rozdzielonych spacjami (z uwzględnieniem wielkości liter).
token_type Typ zwróconego tokena. Obecnie wartość tego pola jest zawsze ustawiona na Bearer.

Ten fragment kodu zawiera przykładową odpowiedź:

{
  "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
  "expires_in": 3920,
  "token_type": "Bearer",
  "scope": "https://www.googleapis.com/auth/drive.metadata.readonly",
  "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
}

Błędy

Podczas wymiany kodu autoryzacji na token dostępu zamiast oczekiwanej odpowiedzi możesz napotkać poniższy błąd. Poniżej znajdziesz typowe kody błędów i zalecane sposoby ich rozwiązania.

invalid_grant

Podany kod autoryzacji jest nieprawidłowy lub ma nieprawidłowy format. Aby poprosić użytkownika o nowy kod, uruchom ponownie proces OAuth.

Wywoływanie interfejsów API Google

PHP

Za pomocą tokena dostępu możesz wywoływać interfejsy API Google, wykonując te czynności:

  1. Jeśli chcesz zastosować token dostępu do nowego obiektu Google\Client – na przykład gdy token dostępu był przechowywany w sesji użytkownika – użyj metody setAccessToken:
    $client->setAccessToken($access_token);
  2. Utwórz obiekt usługi dla interfejsu API, który chcesz wywoływać. Obiekt usługi tworzysz, podając konstruktorowi autoryzowany obiekt Google\Client dla interfejsu API, który chcesz wywoływać. Aby na przykład wywołać interfejs Drive API:
    $drive = new Google\Service\Drive($client);
  3. Wysyłaj żądania do usługi API, korzystając z interfejsu udostępnionego przez obiekt usługi. Aby na przykład wyświetlić listę plików na Dysku Google uwierzytelnionego użytkownika:
    $files = $drive->files->listFiles(array())->getItems();

Python

Po uzyskaniu tokena dostępu aplikacja może go używać do autoryzowania żądań interfejsu API w imieniu danego konta użytkownika lub konta usługi. Użyj danych logowania do konkretnego użytkownika, aby utworzyć obiekt usługi dla interfejsu API, który chcesz wywoływać, a potem użyj tego obiektu do wysłania autoryzowanych żądań do interfejsu API.

  1. Utwórz obiekt usługi dla interfejsu API, który chcesz wywoływać. Obiekt usługi tworzysz, wywołując metodę build biblioteki googleapiclient.discovery z nazwą i wersją interfejsu API oraz danymi logowania użytkownika: Aby na przykład wywołać wersję 3 interfejsu Drive API:
    from googleapiclient.discovery import build
    
    drive = build('drive', 'v2', credentials=credentials)
  2. Wysyłaj żądania do usługi API, korzystając z interfejsu udostępnionego przez obiekt usługi. Aby na przykład wyświetlić listę plików na Dysku Google uwierzytelnionego użytkownika:
    files = drive.files().list().execute()

Ruby

Po uzyskaniu tokena dostępu aplikacja może za jego pomocą wysyłać żądania do interfejsu API w imieniu danego konta użytkownika lub konta usługi. Użyj danych logowania do konkretnego użytkownika, aby utworzyć obiekt usługi dla interfejsu API, który chcesz wywoływać, a potem użyj tego obiektu do wysłania autoryzowanych żądań do interfejsu API.

  1. Utwórz obiekt usługi dla interfejsu API, który chcesz wywoływać. Aby na przykład wywołać wersję 3 interfejsu Drive API:
    drive = Google::Apis::DriveV3::DriveService.new
  2. Ustaw dane logowania w usłudze:
    drive.authorization = credentials
  3. Wyślij żądania do usługi API, korzystając z interfejsu udostępnionego przez obiekt usługi. Aby na przykład wyświetlić listę plików na Dysku Google uwierzytelnionego użytkownika:
    files = drive.list_files

Autoryzację można też zapewnić dla poszczególnych metod, podając parametr options metody:

files = drive.list_files(options: { authorization: credentials })

Node.js

Po uzyskaniu tokena dostępu i ustawieniu go na obiekt OAuth2 użyj tego obiektu do wywoływania interfejsów API Google. Aplikacja może używać tego tokena do autoryzowania żądań do interfejsu API w imieniu danego konta użytkownika lub konta usługi. Utwórz obiekt usługi dla interfejsu API, który chcesz wywoływać.

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

Gdy aplikacja uzyska token dostępu, możesz za jego pomocą wywoływać interfejs API Google w imieniu danego konta użytkownika, jeśli zostały przyznane zakresy dostępu wymagane przez interfejs API. Aby to zrobić, dołącz token dostępu do żądania wysyłanego do interfejsu API, uwzględniając parametr zapytania access_token lub wartość nagłówka HTTP Authorization Bearer. W miarę możliwości preferowany jest nagłówek HTTP, ponieważ ciągi zapytań są zwykle widoczne w logach serwera. W większości przypadków możesz użyć biblioteki klienta do skonfigurowania wywołań interfejsów API Google (na przykład podczas wywoływania interfejsu Drive Files API).

Wszystkie interfejsy API Google możesz wypróbować na stronie OAuth 2.0 Playground.

Przykłady HTTP GET

Wywołanie punktu końcowego drive.files (interfejsu Drive Files API) przy użyciu nagłówka HTTP Authorization: Bearer może wyglądać tak. Pamiętaj, że musisz określić własny token dostępu:

GET /drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token

Oto wywołanie tego samego interfejsu API dla uwierzytelnionego użytkownika za pomocą parametru ciągu zapytania access_token:

GET https://www.googleapis.com/drive/v2/files?access_token=access_token

Przykłady zapytań z operatorem curl

Możesz przetestować te polecenia w aplikacji wiersza poleceń curl. Oto przykład użycia opcji nagłówka HTTP (preferowane):

curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files

Możesz też użyć opcji parametru ciągu zapytania:

curl https://www.googleapis.com/drive/v2/files?access_token=access_token

Pełny przykład

Poniższy przykład umożliwia wydrukowanie w formacie JSON listy plików na Dysku Google użytkownika po uwierzytelnieniu użytkownika i wyrażeniu zgody na dostęp aplikacji do jego metadanych na Dysku.

PHP

Aby uruchomić ten przykład:

  1. W API Consoledodaj adres URL komputera lokalnego do listy przekierowań, np. dodaj http://localhost:8080.
  2. Utwórz nowy katalog i przejdź do niego. Przykład:
    mkdir ~/php-oauth2-example
    cd ~/php-oauth2-example
  3. Zainstaluj bibliotekę klienta interfejsów API Google dla języka PHP za pomocą narzędzia Composer:
    composer require google/apiclient:^2.10
  4. Utwórz pliki index.php i oauth2callback.php z poniższymi treściami.
  5. Uruchom przykład z serwerem WWW skonfigurowanym do obsługi języka PHP. Jeśli korzystasz z języka PHP w wersji 5.6 lub nowszej, możesz użyć wbudowanego testowego serwera WWW PHP:
    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_secrets.json');
$client->addScope(Google\Service\Drive::DRIVE_METADATA_READONLY);

if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
  $client->setAccessToken($_SESSION['access_token']);
  $drive = new Google\Service\Drive($client);
  $files = $drive->files->listFiles(array())->getItems();
  echo json_encode($files);
} else {
  $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();
$client->setAuthConfigFile('client_secrets.json');
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');
$client->addScope(Google\Service\Drive::DRIVE_METADATA_READONLY);

if (! isset($_GET['code'])) {
  $auth_url = $client->createAuthUrl();
  header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
} else {
  $client->authenticate($_GET['code']);
  $_SESSION['access_token'] = $client->getAccessToken();
  $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/';
  header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}

Python

W tym przykładzie użyto platformy Flask. W http://localhost:8080 działa w nim aplikacja internetowa, która pozwala przetestować przepływ OAuth 2.0. Po otwarciu tego adresu URL powinny być widoczne 4 linki:

  • Testowanie żądania do interfejsu API: ten link prowadzi do strony, która próbuje wykonać przykładowe żądanie do interfejsu API. W razie potrzeby uruchamia proces autoryzacji. Jeśli operacja się uda, na stronie wyświetli się odpowiedź interfejsu API.
  • Przetestuj bezpośrednio proces uwierzytelniania: ten link prowadzi do strony, która próbuje przesłać użytkownika przez proces autoryzacji. Aplikacja prosi o uprawnienia do przesyłania w imieniu użytkownika autoryzowanych żądań do interfejsu API.
  • Anuluj bieżące dane logowania: ten link prowadzi do strony, która anuluje uprawnienia przyznane tej aplikacji przez użytkownika.
  • Wyczyść dane uwierzytelniające sesji Flask: ten link usuwa dane logowania zapisane w sesji Flask. Pozwala to sprawdzić, co się stanie, jeśli użytkownik, który przyznał już aplikacji uprawnienia, próbował wykonać żądanie do interfejsu API w nowej sesji. Pokazuje on też odpowiedź interfejsu API, którą otrzymałaby aplikacja, gdy użytkownik unieważnił uprawnienia przyznane Twojej aplikacji, a aplikacja nadal próbowała autoryzować żądanie za pomocą unieważnionego tokena dostępu.
# -*- 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"

# This OAuth 2.0 access scope allows for full read/write access to the
# authenticated user's account and requires requests to use an SSL connection.
SCOPES = ['https://www.googleapis.com/auth/drive.metadata.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('/test')
def test_api_request():
  if 'credentials' not in flask.session:
    return flask.redirect('authorize')

  # 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)


@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
  flask.session['credentials'] = credentials_to_dict(credentials)

  return flask.redirect(flask.url_for('test_api_request'))


@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,
          'scopes': credentials.scopes}

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'

  # 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

W tym przykładzie użyto platformy Sinatra.

require 'google/apis/drive_v3'
require 'sinatra'
require 'googleauth'
require 'googleauth/stores/redis_token_store'

configure do
  enable :sessions

  set :client_id, Google::Auth::ClientId.from_file('/path/to/client_secret.json')
  set :scope, Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY
  set :token_store, Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new)
  set :authorizer, Google::Auth::WebUserAuthorizer.new(settings.client_id, settings.scope, settings.token_store, '/oauth2callback')
end

get '/' do
  user_id = settings.client_id.id
  credentials = settings.authorizer.get_credentials(user_id, request)
  if credentials.nil?
    redirect settings.authorizer.get_authorization_url(login_hint: user_id, request: request)
  end
  drive = Google::Apis::DriveV3::DriveService.new
  files = drive.list_files(options: { authorization: credentials })
  "<pre>#{JSON.pretty_generate(files.to_h)}</pre>"
end

get '/oauth2callback' do
  target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request)
  redirect target_url
end

Node.js

Aby uruchomić ten przykład:

  1. W API Consoledodaj adres URL komputera lokalnego do listy przekierowań, np. dodaj http://localhost.
  2. Sprawdź, czy masz zainstalowany kanał LTS do konserwacji, aktywny kanał LTS lub aktualną wersję Node.js.
  3. Utwórz nowy katalog i przejdź do niego. Przykład:
    mkdir ~/nodejs-oauth2-example
    cd ~/nodejs-oauth2-example
  4. Install the Google API Client Library for Node.js using npm:
    npm install googleapis
  5. Utwórz pliki main.js z poniższymi treściami.
  6. Uruchom przykład:
    node .\main.js

main.js

const http = require('http');
const https = require('https');
const url = require('url');
const { google } = require('googleapis');

/**
 * 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 read-only Drive activity.
const scopes = [
  'https://www.googleapis.com/auth/drive.metadata.readonly'
];

// Generate a url that asks permissions for the Drive activity 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
});

/* 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 server = http.createServer(async function (req, res) {
    // Example on redirecting user to Google's OAuth 2.0 server.
    if (req.url == '/') {
      res.writeHead(301, { "Location": authorizationUrl });
    }

    // Receive the callback from Google's OAuth 2.0 server.
    if (req.url.startsWith('/oauth2callback')) {
      // 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 { // 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;

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

    // Example on revoking a token
    if (req.url == '/revoke') {
      // 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();
    }
    res.end();
  }).listen(80);
}
main().catch(console.error);

HTTP/REST

W tym przykładzie w Pythonie użyto platformy Flask i biblioteki Requests, aby zademonstrować przepływ sieciowy OAuth 2.0. Do tego procesu zalecamy użycie biblioteki klienta interfejsów API Google dla Pythona. (W przykładzie na karcie Python użyto biblioteki klienta).

import json

import flask
import requests


app = flask.Flask(__name__)

CLIENT_ID = '123456789.apps.googleusercontent.com'
CLIENT_SECRET = 'abc123'  # Read from a file or environmental variable in a real app
SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly'
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:
    headers = {'Authorization': 'Bearer {}'.format(credentials['access_token'])}
    req_uri = 'https://www.googleapis.com/drive/v2/files'
    r = requests.get(req_uri, headers=headers)
    return r.text


@app.route('/oauth2callback')
def oauth2callback():
  if 'code' not in flask.request.args:
    auth_uri = ('https://accounts.google.com/o/oauth2/v2/auth?response_type=code'
                '&client_id={}&redirect_uri={}&scope={}').format(CLIENT_ID, REDIRECT_URI, SCOPE)
    return flask.redirect(auth_uri)
  else:
    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'}
    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()

Reguły weryfikacji identyfikatora URI przekierowania

Do przekierowania identyfikatorów URI Google stosuje poniższe reguły weryfikacji, by pomóc programistom chronić ich aplikacje. Identyfikatory URI przekierowania muszą być zgodne z tymi regułami. Definicję domeny, hosta, ścieżki, zapytania, schematu i informacji o użytkowniku znajdziesz w sekcji 3 RFC 3986.

Reguły weryfikacji
Schemat

Identyfikatory URI przekierowań muszą korzystać ze schematu HTTPS, a nie zwykłego protokołu HTTP. Identyfikatory URI lokalnego hosta (w tym identyfikatory URI adresu IP lokalnego hosta) są zwolnione z tej reguły.

Osoba prowadząca

Hosty nie mogą być nieprzetworzonymi adresami IP. Adresy IP lokalnego hosta są wykluczone z tej reguły.

Domena
  • Domeny najwyższego poziomu hosta (domeny najwyższego poziomu) muszą należeć do listy domen publicznych.
  • Domeny hosta nie mogą być typu “googleusercontent.com”.
  • Identyfikatory URI przekierowań nie mogą zawierać domen skracających adresy URL (np. goo.gl), chyba że domena należy do aplikacji. Ponadto, jeśli aplikacja będąca właścicielem domeny skracającej decydują się na przekierowanie do tej domeny, identyfikator URI przekierowania musi zawierać w ścieżce “/google-callback/” lub kończyć się ciągiem “/google-callback”.
  • Informacje o użytkowniku

    Identyfikatory URI przekierowań nie mogą zawierać podkomponentu informacji o użytkowniku.

    Ścieżka

    Identyfikatory URI przekierowań nie mogą zawierać informacji o przemierzaniu ścieżki (nazywanym też śledzeniem wstecznym katalogu), które jest reprezentowane przez kodowanie “/..” lub “\..” albo ich kodowanie adresu URL.

    Zapytanie

    Identyfikatory URI przekierowań nie mogą zawierać otwartych przekierowań.

    Fragment

    Identyfikatory URI przekierowań nie mogą zawierać komponentu fragmentu.

    Znaki Identyfikatory URI przekierowań nie mogą zawierać niektórych znaków, w tym:
    • Symbole wieloznaczne ('*')
    • Niedrukowalne znaki ASCII
    • Nieprawidłowe kodowanie procentowe (dowolne kodowanie procentowe niezgodne z formatem adresu URL ze znakiem procentu, po którym następują 2 cyfry szesnastkowe)
    • Znaki null (zakodowany znak NULL, np. %00, %C0%80)

    Autoryzacja przyrostowa

    W protokole OAuth 2.0 aplikacja żąda autoryzacji dostępu do zasobów identyfikowanych przez zakresy. Żądanie autoryzacji zasobów we właściwym momencie jest uważane za najlepszą metodę dla użytkowników. Aby umożliwić korzystanie z tej metody, serwer autoryzacji Google obsługuje autoryzację przyrostową. Ta funkcja pozwala żądać zakresów w razie potrzeby oraz, jeśli użytkownik przyzna uprawnienia do nowego zakresu, zwraca kod autoryzacji, który można wymienić na token zawierający wszystkie zakresy przyznane projektowi przez użytkownika.

    Na przykład aplikacja, która umożliwia użytkownikom próbkowanie utworów muzycznych i tworzenie składanek, może wymagać bardzo niewielu zasobów w momencie logowania – być może nie wystarczy imię i nazwisko zalogowanej osoby. Żeby zapisać gotową składankę, trzeba mieć jednak dostęp do Dysku Google. Dla większości osób byłoby to naturalne, gdyby poproszono ich tylko o dostęp do Dysku Google w momencie, gdy aplikacja rzeczywiście tego potrzebowała.

    W tym przypadku w momencie logowania aplikacja może zażądać zakresów openid i profile w celu przeprowadzenia podstawowego logowania, a następnie w momencie pierwszego żądania zapisania składanki zażądać zakresu https://www.googleapis.com/auth/drive.file.

    Aby wdrożyć autoryzację przyrostową, wykonaj zwykłą procedurę żądania tokena dostępu, ale upewnij się, że żądanie autoryzacji zawiera zakresy przyznane wcześniej. Dzięki temu aplikacja uniknie konieczności zarządzania wieloma tokenami dostępu.

    Do tokena dostępu uzyskanego dzięki autoryzacji przyrostowej obowiązują te reguły:

    • Token można używać do uzyskiwania dostępu do zasobów odpowiadających dowolnym zakresom wdrożonym w nowej, połączonej autoryzacji.
    • Gdy w celu uzyskania tokena dostępu używasz tokena odświeżania połączonej autoryzacji, token dostępu reprezentuje połączoną autoryzację i może być użyty w przypadku dowolnej z wartości scope zawartych w odpowiedzi.
    • Połączona autoryzacja obejmuje wszystkie zakresy przyznane przez użytkownika projektowi API, nawet jeśli o przyznanie tych uprawnień zażądano różne klienty. Jeśli na przykład użytkownik przyznał dostęp do jednego zakresu za pomocą klienta aplikacji na komputer, a następnie przyznał inny zakres tej samej aplikacji za pomocą klienta mobilnego, łączna autoryzacja obejmie oba zakresy.
    • Jeśli unieważnisz token reprezentujący połączoną autoryzację, dostęp do wszystkich zakresów tej autoryzacji w imieniu powiązanego użytkownika zostanie jednocześnie unieważniony.

    Przykładowe fragmenty kodu w różnych językach podane w kroku 1. Ustaw parametry autoryzacji i przykładowe przekierowanie HTTP/REST w kroku 2. Przekieruj na serwer OAuth 2.0 Google korzystają z autoryzacji przyrostowej. Poniższe przykłady kodu zawierają też kod, który musisz dodać, aby korzystać z autoryzacji przyrostowej.

    PHP

    $client->setIncludeGrantedScopes(true);

    Python

    W Pythonie ustaw argument słowa kluczowego include_granted_scopes na true, aby mieć pewność, że żądanie autoryzacji obejmuje zakresy przyznane wcześniej. Bardzo może się zdarzyć, że include_granted_scopes nie będzie jedynym argumentem słowa kluczowego, jak pokazano w poniższym przykładzie.

    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.file&
      redirect_uri=https%3A//oauth2.example.com/code&
      prompt=consent&
      include_granted_scopes=true

    Odświeżanie tokena dostępu (dostęp offline)

    Tokeny dostępu okresowo tracą ważność i stają się nieważnymi danymi uwierzytelniającymi dla powiązanego żądania do interfejsu API. Możesz odświeżyć token dostępu bez pytania użytkownika o zgodę (także wtedy, gdy użytkownika nie ma), jeśli poprosisz o dostęp offline do zakresów powiązanych z tokenem.

    • Jeśli używasz biblioteki klienta interfejsów API Google, obiekt klienta odświeża token dostępu w razie potrzeby, o ile obiekt jest skonfigurowany do dostępu offline.
    • Jeśli nie używasz biblioteki klienta, ustaw parametr zapytania HTTP access_type na offline podczas przekierowania użytkownika na serwer Google OAuth 2.0. W takim przypadku serwer autoryzacji Google zwraca token odświeżania, gdy wymieniasz kod autoryzacji na token dostępu. Następnie, gdy token dostępu wygaśnie (lub w dowolnym innym momencie), możesz użyć tokena odświeżania, aby uzyskać nowy.

    Żądanie dostępu offline jest wymagane w przypadku każdej aplikacji, która musi mieć dostęp do interfejsu Google API, gdy użytkownik nie jest obecny. Na przykład aplikacja, która wykonuje usługi tworzenia kopii zapasowych lub wykonuje działania w określonych godzinach, musi mieć możliwość odświeżania swojego tokena dostępu w przypadku nieobecności użytkownika. Domyślny styl dostępu to online.

    Aplikacje internetowe, zainstalowane aplikacje i urządzenia po stronie serwera otrzymują tokeny odświeżania podczas procesu autoryzacji. Tokeny odświeżania zwykle nie są używane w aplikacjach internetowych (JavaScript) po stronie klienta.

    PHP

    Jeśli Twoja aplikacja wymaga dostępu w trybie offline do interfejsu Google API, ustaw typ dostępu klienta interfejsu API na offline:

    $client->setAccessType("offline");

    Gdy użytkownik przyzna dostęp offline do żądanych zakresów, nadal będzie można używać klienta interfejsu API do uzyskiwania w jego imieniu interfejsów API Google, gdy użytkownik jest offline. Obiekt klienta będzie w razie potrzeby odświeżać token dostępu.

    Python

    W Pythonie ustaw argument słowa kluczowego access_type na offline, aby mieć pewność, że będzie można odświeżyć token dostępu bez konieczności ponownego proszenia użytkownika o zgodę. Bardzo może się zdarzyć, że access_type nie będzie jedynym argumentem dotyczącym słowa kluczowego, jak pokazano w poniższym przykładzie.

    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')

    Gdy użytkownik przyzna dostęp offline do żądanych zakresów, nadal będzie można używać klienta interfejsu API do uzyskiwania w jego imieniu interfejsów API Google, gdy użytkownik jest offline. Obiekt klienta będzie w razie potrzeby odświeżać token dostępu.

    Ruby

    Jeśli Twoja aplikacja wymaga dostępu w trybie offline do interfejsu Google API, ustaw typ dostępu klienta interfejsu API na offline:

    auth_client.update!(
      :additional_parameters => {"access_type" => "offline"}
    )

    Gdy użytkownik przyzna dostęp offline do żądanych zakresów, nadal będzie można używać klienta interfejsu API do uzyskiwania w jego imieniu interfejsów API Google, gdy użytkownik jest offline. Obiekt klienta będzie w razie potrzeby odświeżać token dostępu.

    Node.js

    Jeśli Twoja aplikacja wymaga dostępu w trybie offline do interfejsu Google API, ustaw typ dostępu klienta interfejsu API na offline:

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

    Gdy użytkownik przyzna dostęp offline do żądanych zakresów, nadal będzie można używać klienta interfejsu API do uzyskiwania w jego imieniu interfejsów API Google, gdy użytkownik jest offline. Obiekt klienta będzie w razie potrzeby odświeżać token dostępu.

    Tokeny dostępu wygasają. Ta biblioteka automatycznie użyje tokena odświeżania, aby uzyskać nowy token dostępu, jeśli będzie on wkrótce wygasał. Aby mieć pewność, że zawsze będą przechowywane najnowsze tokeny, użyj zdarzenia tokenów:

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

    To zdarzenie związane z tokenem występuje tylko podczas pierwszej autoryzacji. Aby otrzymać token odświeżania, podczas wywoływania metody generateAuthUrl musisz ustawić access_type na offline. Jeśli aplikacja otrzymała już wymagane uprawnienia bez ustawienia odpowiednich ograniczeń dotyczących odbioru tokena odświeżania, musisz ponownie autoryzować aplikację, aby otrzymała nowy token odświeżania.

    Aby później ustawić refresh_token, możesz użyć metody setCredentials:

    oauth2Client.setCredentials({
      refresh_token: `STORED_REFRESH_TOKEN`
    });
    

    Gdy klient ma token odświeżania, tokeny dostępu będą automatycznie pobierane i odświeżane w następnym wywołaniu interfejsu API.

    HTTP/REST

    Aby odświeżyć token dostępu, aplikacja wysyła żądanie HTTPS POST do serwera autoryzacji Google (https://oauth2.googleapis.com/token) zawierające te parametry:

    Pola
    client_id Identyfikator klienta uzyskany z: API Console.
    client_secret Tajny klucz klienta uzyskany z: API Console.
    grant_type Zgodnie z definicją w specyfikacji OAuth 2.0 wartość tego pola musi być ustawiona na refresh_token.
    refresh_token Token odświeżania zwrócony z wymiany kodów autoryzacji.

    Ten fragment kodu zawiera przykładowe żądanie:

    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

    Dopóki użytkownik nie unieważnił dostępu przyznanego aplikacji, serwer tokenów zwraca obiekt JSON zawierający nowy token dostępu. Ten fragment kodu zawiera przykładową odpowiedź:

    {
      "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
      "expires_in": 3920,
      "scope": "https://www.googleapis.com/auth/drive.metadata.readonly",
      "token_type": "Bearer"
    }

    Zwróć uwagę, że istnieją limity liczby tokenów odświeżania: jeden limit na kombinację klienta/użytkownika i jeden na użytkownika w przypadku wszystkich klientów. Zapisuj tokeny odświeżania w pamięci długoterminowej i używaj ich, dopóki pozostają ważne. Jeśli Twoja aplikacja żąda zbyt wielu tokenów odświeżania, może dojść do osiągnięcia tych limitów. W takim przypadku starsze tokeny odświeżania przestaną działać.

    Unieważnianie tokena

    W niektórych przypadkach użytkownik może zechcieć anulować dostęp przyznany aplikacji. Użytkownik może anulować dostęp w Ustawieniach konta. Więcej informacji znajdziesz w sekcji Usuwanie dostępu witryny lub aplikacji do witryny lub aplikacji innych firm, które mają dostęp do Twojego konta.

    Aplikacja może też automatycznie anulować przyznany jej dostęp. Automatyczne unieważnienie jest ważne w sytuacjach, gdy użytkownik anuluje subskrypcję, usunie aplikację lub znacząco zmieniły się wymagane przez aplikację zasoby interfejsu API. Inaczej mówiąc, część procesu usuwania może obejmować żądanie do interfejsu API, aby mieć pewność, że uprawnienia przyznane wcześniej aplikacji zostaną usunięte.

    PHP

    Aby programowo unieważnić token, wywołaj revokeToken():

    $client->revokeToken();

    Python

    Aby automatycznie unieważnić token, wyślij do https://oauth2.googleapis.com/revoke żądanie, które zawiera token jako parametr i ustawia nagłówek Content-Type:

    requests.post('https://oauth2.googleapis.com/revoke',
        params={'token': credentials.token},
        headers = {'content-type': 'application/x-www-form-urlencoded'})

    Ruby

    Aby automatycznie unieważnić token, wyślij żądanie HTTP do punktu końcowego oauth2.revoke:

    uri = URI('https://oauth2.googleapis.com/revoke')
    response = Net::HTTP.post_form(uri, 'token' => auth_client.access_token)
    

    Tokenem może być token dostępu lub token odświeżania. Jeśli token jest tokenem dostępu i ma odpowiedni token odświeżania, token odświeżania również zostanie unieważniony.

    Jeśli odwołanie zostanie przetworzone, kod stanu odpowiedzi to 200. W przypadku wystąpienia błędu zwracany jest kod stanu 400 wraz z kodem błędu.

    Node.js

    Aby automatycznie unieważnić token, wyślij żądanie HTTPS POST do punktu końcowego /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();
    

    Parametrem tokena może być token dostępu lub token odświeżania. Jeśli token jest tokenem dostępu i ma odpowiedni token odświeżania, token odświeżania również zostanie unieważniony.

    Jeśli odwołanie zostanie przetworzone, kod stanu odpowiedzi to 200. W przypadku wystąpienia błędu zwracany jest kod stanu 400 wraz z kodem błędu.

    HTTP/REST

    Aby programowo unieważnić token, aplikacja wysyła żądanie do https://oauth2.googleapis.com/revoke i uwzględnia token jako parametr:

    curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \
            https://oauth2.googleapis.com/revoke?token={token}

    Tokenem może być token dostępu lub token odświeżania. Jeśli token jest tokenem dostępu i ma odpowiedni token odświeżania, token odświeżania również zostanie unieważniony.

    Jeśli odwołanie zostanie przetworzone, kod stanu HTTP odpowiedzi to 200. W przypadku błędu zwracany jest kod stanu HTTP 400 wraz z kodem błędu.