Korzystanie z protokołu OAuth 2.0 w aplikacjach serwerowych

Ten dokument wyjaśnia, jak aplikacje serwerów WWW korzystają z bibliotek klienta interfejsów API Google lub punktów końcowych Google OAuth 2.0 do implementacji autoryzacji OAuth 2.0 na potrzeby uzyskiwania dostępu do interfejsu YouTube Data API.

OAuth 2.0 umożliwia użytkownikom udostępnianie określonych danych aplikacji przy jednoczesnym zachowaniu prywatności nazw użytkowników, haseł i innych informacji. Na przykład aplikacja może korzystać z OAuth 2.0, aby uzyskać pozwolenie na pobranie danych kanału z YouTube.

Ten proces OAuth 2.0 jest przeznaczony specjalnie do autoryzacji użytkowników. Jest on przeznaczony dla aplikacji, które mogą przechowywać informacje poufne i utrzymywać stan. 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 serwerów WWW często używają też kont usługi do autoryzowania żądań interfejsu API, zwłaszcza gdy wywołujesz interfejsy Cloud APIs w celu uzyskania dostępu do danych projektu, a nie danych poszczególnych użytkowników. Aplikacje serwera WWW mogą używać kont usługi w połączeniu z autoryzacją użytkownika.

Interfejs YouTube Live Streaming API nie obsługuje procesu konta usługi. Nie ma możliwości powiązania konta usługi z kontem YouTube, dlatego próby autoryzacji żądań za pomocą tego procesu spowodują wygenerowanie błędu NoLinkedYouTubeAccount.

Biblioteki klienta

Przykłady w konkretnych językach na tej stronie wykorzystują biblioteki klienta interfejsów API Google do implementacji autoryzacji OAuth 2.0. Aby uruchomić przykładowy kod, musisz najpierw zainstalować bibliotekę klienta dla swojego języka.

Gdy do obsługi przepływu protokołu OAuth 2.0 w aplikacji używasz biblioteki klienta interfejsu API Google, biblioteka klienta wykonuje wiele działań, które w innym przypadku musiałaby wykonać samodzielnie. Określa na przykład, kiedy aplikacja może używać lub odświeżać przechowywanych tokenów dostępu oraz kiedy aplikacja musi ponownie uzyskać zgodę. 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 do aplikacji po stronie serwera są dostępne w następujących językach:

Wymagania wstępne

Włączanie interfejsów API w projekcie

Każda aplikacja, która wywołuje interfejsy API Google, musi je włączyć w 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. Znajdź i włącz interfejs YouTube Data API, korzystając ze strony Biblioteka. Znajdź i włącz wszystkie inne interfejsy API, których będzie używać Twoja aplikacja.

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żej znajdziesz instrukcje tworzenia danych logowania dla projektu. Aplikacje będą mogły używać tych danych logowania do uzyskiwania dostępu 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. Jako typ aplikacji wybierz 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, które odnoszą się do komputera lokalnego, np. 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 w taki sposób, aby aplikacja nie ujawniała kodów autoryzacji innym zasobom na stronie.

Po utworzeniu danych logowania pobierz plik client_secret.json z API Console. Bezpiecznie przechowuj plik w lokalizacji, do której ma dostęp tylko Twoja aplikacja.

Określanie zakresów dostępu

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

Zanim zaczniesz wdrażać autoryzację OAuth 2.0, zalecamy określenie zakresów, do których aplikacja będzie potrzebować uprawnień dostępu.

Zalecamy też, aby aplikacja żądała dostępu do zakresów autoryzacji za pomocą procesu autoryzacji przyrostowej, w którym aplikacja żąda dostępu do danych użytkownika w kontekście. Ta sprawdzona metoda pomaga użytkownikom łatwiej zrozumieć, dlaczego aplikacja potrzebuje dostępu, o który prosi.

Interfejs YouTube Data API w wersji 3 korzysta z tych zakresów:

Zakresy
https://www.googleapis.com/auth/youtubeZarządzanie kontem YouTube
https://www.googleapis.com/auth/youtube.channel-memberships.creatorWyświetlanie listy aktualnie aktywnych użytkowników wspierających kanał, ich obecnych poziomów i dat rozpoczęcia wsparcia
https://www.googleapis.com/auth/youtube.force-sslPrzeglądanie, edytowanie i trwałe usuwanie Twoich filmów, ocen, komentarzy i napisów z YouTube
https://www.googleapis.com/auth/youtube.readonlyWyświetlanie konta YouTube
https://www.googleapis.com/auth/youtube.uploadZarządzanie filmami w YouTube
https://www.googleapis.com/auth/youtubepartnerPrzeglądaj zasoby oraz powiązane treści i zarządzaj nimi w serwisie YouTube
https://www.googleapis.com/auth/youtubepartner-channel-auditPrzeglądanie prywatnych danych kanału YouTube istotnych podczas rozmowy z partnerem YouTube

Dokument Zakresy interfejsu API OAuth 2.0 zawiera pełną listę zakresów, których możesz używać do uzyskiwania dostępu do interfejsów API Google.

Wymagania dla poszczególnych języków

Aby uruchomić dowolny z przykładowego kodu w tym dokumencie, potrzebujesz konta Google, dostępu do internetu i przeglądarki. Jeśli używasz jednej z bibliotek klienta interfejsu API, zapoznaj się też z poniższymi wymaganiami dotyczącymi języka.

PHP

Do uruchomienia przykładowego kodu w języku PHP w tym dokumencie będziesz potrzebować:

  • Interfejs 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

Do uruchomienia przykładowego kodu w Pythonie w tym dokumencie będziesz potrzebować:

  • Python w wersji 2.6 lub nowszej
  • Narzędzie do zarządzania pakietami pip.
  • Biblioteka klienta interfejsów API Google dla Pythona:
    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 w Pythonie.
    pip install --upgrade flask
  • Biblioteka HTTP requests.
    pip install --upgrade requests

Ruby

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

  • Ruby w wersji 2.6 lub nowszej
  • Google Auth Library dla Ruby:

    gem install googleauth
  • platforma aplikacji internetowej Sinatra Ruby;

    gem install sinatra

Node.js

Do uruchomienia przykładowego kodu w środowisku Node.js w tym dokumencie będziesz potrzebować:

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

    npm install googleapis crypto express express-session

HTTP/REST

Nie musisz instalować żadnych bibliotek, aby móc bezpośrednio wywoływać punkty końcowe OAuth 2.0.

Uzyskiwanie tokenów dostępu OAuth 2.0

Z podanych niżej instrukcji dowiesz się, jak Twoja aplikacja wchodzi w interakcję z serwerem Google OAuth 2.0, aby uzyskać zgodę użytkownika na wykonanie żądania do interfejsu API w jego imieniu. Twoja aplikacja musi uzyskać tę zgodę, zanim będzie mogła wykonać żądanie do interfejsu API Google wymagające autoryzacji użytkownika.

Oto krótkie podsumowanie tych czynności:

  1. Aplikacja określa wymagane uprawnienia.
  2. Twoja aplikacja przekierowuje użytkownika do Google wraz z listą wymaganych uprawnień.
  3. Użytkownik decyduje, czy przyznać aplikacji uprawnienia.
  4. Aplikacja uzyskuje informacje na temat decyzji 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

Pierwszym krokiem jest utworzenie żądania autoryzacji. Żądanie to ustawia parametry identyfikujące aplikację oraz definiując uprawnienia, które użytkownik będzie musiał przyznać.

  • Jeśli używasz biblioteki klienta Google do uwierzytelniania i autoryzacji OAuth 2.0, utworzysz i skonfigurujesz obiekt definiujący te parametry.
  • Jeśli wywołasz punkt końcowy Google OAuth 2.0 bezpośrednio, wygenerujesz adres URL i ustawisz dla niego parametry.

Poniższe karty określają obsługiwane parametry autoryzacji aplikacji serwera WWW. Przykłady w konkretnych językach pokazują też, jak skonfigurować obiekt ustawiający te parametry za pomocą biblioteki klienta lub biblioteki autoryzacji.

PHP

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

Ten obiekt identyfikuje aplikację na podstawie informacji z pliku client_secret.json. Więcej informacji o tym pliku znajdziesz w artykule o tworzeniu danych uwierzytelniających. Obiekt określa też zakresy, do których aplikacja żąda uprawnień dostępu, oraz adres URL punktu końcowego uwierzytelniania aplikacji, który przetwarza odpowiedź z serwera Google OAuth 2.0. Na koniec kod ustawia opcjonalne parametry access_type i include_granted_scopes.

Aby na przykład poprosić o dostęp offline do pobrania danych użytkownika z YouTube:

$client = new Google\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_YouTube::YOUTUBE_FORCE_SSL);

// 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

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 uwierzytelniających. Ten obiekt identyfikuje zakresy, do których aplikacja żąda uprawnień dostępu, oraz adres URL punktu końcowego uwierzytelniania aplikacji, który przetwarza odpowiedź z serwera Google OAuth 2.0. Na koniec kod ustawia opcjonalne parametry access_type i include_granted_scopes.

Aby na przykład poprosić o dostęp offline do pobrania danych użytkownika z YouTube:

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/youtube.force-ssl'])

# 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

Użyj utworzonego pliku client_secrets.json, aby skonfigurować obiekt klienta w aplikacji. Podczas konfigurowania obiektu klienta określasz zakresy, do których aplikacja musi uzyskiwać dostęp, wraz z adresem URL punktu końcowego uwierzytelniania aplikacji, który przetwarza odpowiedź z serwera OAuth 2.0.

Aby na przykład poprosić o dostęp offline do pobrania danych użytkownika z YouTube:

require 'google/apis/youtube_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/youtube.force-ssl'
token_store = Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new)
authorizer = Google::Auth::WebUserAuthorizer.new(client_id, scope, token_store, '/oauth2callback')

Aplikacja używa obiektu klienta do wykonywania operacji OAuth 2.0, takich jak generowanie adresów URL żądań autoryzacji i stosowanie tokenów dostępu do żądań HTTP.

Node.js

Ten fragment kodu tworzy obiekt google.auth.OAuth2, który definiuje parametry w żądaniu autoryzacji.

Ten obiekt identyfikuje aplikację na podstawie informacji z pliku client_secret.json. Aby poprosić użytkownika o uprawnienia do pobrania tokena dostępu, musisz przekierować go na stronę z prośbą o zgodę na przetwarzanie danych. Aby utworzyć adres URL strony z prośbą o zgodę na przetwarzanie danych:

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

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

HTTP/REST

Punkt końcowy OAuth 2.0 Google jest 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 w aplikacjach serwera WWW:

Parametry
client_id Wymagane

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

redirect_uri Wymagane

Określa, dokąd serwer interfejsu API przekierowuje użytkownika po zakończeniu procesu autoryzacji przez użytkownika. Wartość musi dokładnie odpowiadać jednemu z autoryzowanych identyfikatorów URI przekierowania klienta OAuth 2.0 skonfigurowanych w: API Console Credentials pageklienta. Jeśli ta wartość nie pasuje do autoryzowanego identyfikatora URI przekierowania w podanej wartości client_id, wystąpi błąd redirect_uri_mismatch.

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

response_type Wymagane

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

W przypadku aplikacji serwera WWW ustaw parametr na code.

scope Wymagane

Rozdzielona spacjami lista zakresów identyfikujących zasoby, do których aplikacja może uzyskiwać dostęp w imieniu użytkownika. Wartości te informują o ekranie zgody, który Google wyświetla użytkownikowi.

Zakresy pozwalają aplikacji prosić o dostęp tylko do zasobów, których potrzebuje, a jednocześnie pozwalają użytkownikom kontrolować zakres dostępu, jaki przyznają aplikacji. Dlatego występuje odwrotna zależność między liczbą żądanych zakresów a prawdopodobieństwem uzyskania zgody użytkownika.

Interfejs YouTube Data API w wersji 3 korzysta z tych zakresów:

Zakresy
https://www.googleapis.com/auth/youtubeZarządzanie kontem YouTube
https://www.googleapis.com/auth/youtube.channel-memberships.creatorWyświetlanie listy aktualnie aktywnych użytkowników wspierających kanał, ich obecnych poziomów i dat rozpoczęcia wsparcia
https://www.googleapis.com/auth/youtube.force-sslPrzeglądanie, edytowanie i trwałe usuwanie Twoich filmów, ocen, komentarzy i napisów z YouTube
https://www.googleapis.com/auth/youtube.readonlyWyświetlanie konta YouTube
https://www.googleapis.com/auth/youtube.uploadZarządzanie filmami w YouTube
https://www.googleapis.com/auth/youtubepartnerPrzeglądaj zasoby oraz powiązane treści i zarządzaj nimi w serwisie YouTube
https://www.googleapis.com/auth/youtubepartner-channel-auditPrzeglądanie prywatnych danych kanału YouTube istotnych podczas rozmowy z partnerem YouTube

Dokument Zakresy interfejsu API OAuth 2.0 zawiera pełną listę zakresów, których możesz używać do uzyskiwania dostępu do interfejsów API Google.

Zalecamy, aby aplikacja żądała dostępu do zakresów autoryzacji w kontekście, gdy tylko jest to możliwe. Prosząc o dostęp do danych użytkownika w kontekście za pomocą dodatkowej autoryzacji, pomagasz użytkownikom zrozumieć, dlaczego Twoja 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 (jest to 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. Jest to metoda odświeżania tokenów dostępu opisanych w dalszej części tego dokumentu. Ta wartość instruuje serwer autoryzacji Google, aby za pierwszym razem, gdy aplikacja wymienia kod autoryzacji na tokeny, zwraca token odświeżania oraz token dostępu.

state Zalecane

Określa dowolną wartość ciągu, której aplikacja używa do utrzymania stanu między żądaniem autoryzacji a odpowiedzią serwera autoryzacji. Serwer zwraca dokładną wartość, którą wysyłasz w postaci pary name=value w komponencie zapytania z adresem URL (?) elementu redirect_uri, gdy użytkownik wyrazi zgodę na dostęp aplikacji lub jej odmówi.

Tego parametru możesz używać do różnych celów, na przykład do kierowania użytkowników do odpowiedniego zasobu w aplikacji, wysyłania liczby jednorazowych i zapobiegania fałszowaniu żądań 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 uwierzytelnienia. Jeśli generujesz losowy ciąg lub kodujesz hasz pliku cookie bądź inną wartość przechwytującą stan klienta, możesz zweryfikować odpowiedź, aby dodatkowo upewnić się, że żądanie i odpowiedź pochodzą z tej samej przeglądarki. Zapewnia to ochronę przed atakami takimi jak oszustwa żądań z innych witryn. Przykład tworzenia i potwierdzania tokena state znajdziesz w dokumentacji OpenID Connect.

include_granted_scopes Opcjonalny

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

login_hint Opcjonalny

Jeśli aplikacja wie, który użytkownik próbuje się uwierzytelnić, może użyć tego parametru, aby podać wskazówkę dla serwera uwierzytelniania Google. Serwer korzysta ze wskazówek, aby uprościć proces logowania. Aby to zrobić, wstępnie wypełnij pole adresu e-mail w formularzu logowania lub wybierz odpowiednią sesję wielokrotnego logowania.

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

prompt Opcjonalny

Rozdzielona spacjami lista promptów, które mają zostać zaprezentowane użytkownikowi. Wielkość liter ma znaczenie. Jeśli nie określisz tego parametru, użytkownik zostanie o to poproszony tylko przy pierwszej prośbie o dostęp z projektu. Więcej informacji znajdziesz w artykule na temat proszenia o ponowne wyrażenie zgody.

Możliwe wartości to:

none Nie wyświetlaj żadnych ekranów uwierzytelniania ani zgody użytkownika. Nie można go określać za pomocą innych wartości.
consent Wyświetl użytkownikowi prośbę o zgodę.
select_account Wyświetlaj użytkownikowi prośbę o wybranie konta.

Krok 2. Przekieruj na serwer OAuth 2.0 Google

Przekieruj użytkownika na serwer Google OAuth 2.0, aby rozpocząć 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 też wtedy, gdy aplikacja najpierw musi uzyskać dostęp do dodatkowych zasobów, do których nie ma jeszcze uprawnień.

PHP

  1. Wygeneruj adres URL, aby poprosić o dostęp z serwera Google OAuth 2.0:
    $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 na adres URL autoryzacji za pomocą platformy aplikacji internetowej Flask:

return flask.redirect(authorization_url)

Ruby

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

Node.js

  1. Użyj adresu URL authorizationUrl wygenerowanego w kroku 1 generateAuthUrl, aby poprosić o dostęp z serwera Google OAuth 2.0.
  2. Przekieruj użytkownika na stronę authorizationUrl.
    res.redirect(authorizationUrl);

HTTP/REST

Sample redirect to Google's authorization server

An example URL is shown below, with line breaks and spaces for readability. The URL requests access to a scope that permits access to retrieve the user's YouTube data. It uses incremental authorization (include_granted_scopes=true) to ensure that the new access token covers any scopes to which the user previously granted the application access. Several other parameters are also set in the example.

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.force-ssl&
 access_type=offline&
 include_granted_scopes=true&
 response_type=code&
 state=state_parameter_passthrough_value&
 redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback&
 client_id=client_id

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

Serwer OAuth 2.0 Google 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 przez Ciebie adresu URL przekierowania.

Krok 3. Google prosi użytkownika o zgodę

Na tym etapie użytkownik decyduje, czy przyznać aplikacji żądany dostęp. Na tym etapie Google wyświetla okno zgody, w którym widoczna jest nazwa Twojej aplikacji i usług interfejsów API Google, do których aplikacja prosi o dostęp (wraz z danymi uwierzytelniającymi użytkownika) oraz podsumowanie zakresów dostępu. Użytkownik może wtedy wyrazić zgodę na przyznanie dostępu do co najmniej 1 zakresu żądanego przez aplikację lub odrzucić żądanie.

Na tym etapie Twoja aplikacja nie musi nic robić, ponieważ czeka na odpowiedź z serwera OAuth 2.0 Google wskazującą, czy przyznano dostęp. Odpowiedź na to pytanie zostanie objaśniona w kolejnym kroku.

Błędy

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

admin_policy_enforced

Konto Google nie może autoryzować co najmniej jednego żądanego zakresu ze względu na zasady administratora 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, przeczytaj artykuł pomocy dla administratorów Google Workspace na temat określania, które aplikacje innych firm i aplikacje wewnętrzne mają dostęp do danych Google Workspace.

disallowed_useragent

Punkt końcowy autoryzacji jest wyświetlany w umieszczonym kliencie użytkownika niedozwolonym przez zasady Google dotyczące protokołu OAuth 2.0.

Android

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

Programiści stron internetowych mogą napotkać ten błąd, gdy aplikacja na Androida otwiera ogólny link internetowy w osadzonym 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 zawiera zarówno linki aplikacji na Androida, jak i domyślną przeglądarkę. Obsługiwana jest też biblioteka kart niestandardowych Androida.

iOS

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

Deweloperzy aplikacji internetowej mogą napotkać ten błąd, gdy aplikacja na iOS lub macOS otwiera ogólny link internetowy w osadzonym 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 w systemie operacyjnym, który zawiera zarówno uniwersalne linki, jak i domyślną aplikację przeglądarki. Obsługiwana jest też biblioteka SFSafariViewController.

org_internal

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

invalid_client

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

invalid_grant

Podczas odświeżania tokena dostępu lub korzystania z autoryzacji przyrostowej token mógł wygasnąć lub został unieważniony. Uwierzytelnij użytkownika ponownie i poproś o zgodę na uzyskanie nowych tokenów. Jeśli ten błąd będzie się powtarzał, sprawdź, czy aplikacja została prawidłowo skonfigurowana 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

redirect_uri przekazany w żądaniu autoryzacji nie pasuje do autoryzowanego identyfikatora URI przekierowania dla identyfikatora klienta OAuth. Przejrzyj autoryzowane identyfikatory URI przekierowania w Google API Console Credentials page.

Parametr redirect_uri może odnosić się do zewnętrznego procesu OAuth (OOB), który został wycofany i nie jest już obsługiwany. Informacje o tym, jak zaktualizować integrację, znajdziesz w przewodniku po migracji.

invalid_request

Coś poszło nie tak z Twoją prośbą. Możliwych jest kilka przyczyn tej sytuacji:

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

Krok 4. Przetwórz odpowiedź serwera OAuth 2.0

Serwer OAuth 2.0 odpowiada na żądanie dostępu aplikacji, korzystając z adresu URL określonego w żądaniu.

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

Odpowiedź o błędzie:

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

Odpowiedź 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 ten przykładowy adres URL, który prosi o dostęp tylko do odczytu z możliwością wyświetlania metadanych plików na Dysku Google:

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.force-ssl&
 access_type=offline&
 include_granted_scopes=true&
 response_type=code&
 state=state_parameter_passthrough_value&
 redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback&
 client_id=client_id

Po zakończeniu procesu OAuth 2.0 nastąpi przekierowanie do http://localhost/oauth2callback. Prawdopodobnie spowoduje to błąd 404 NOT FOUND, chyba że komputer lokalny wyświetli plik pod tym adresem. W następnym kroku znajdziesz więcej informacji na temat informacji zwracanych w identyfikatorze URI, gdy użytkownik jest przekierowywany z powrotem do Twojej aplikacji.

Krok 5. Kod autoryzacji Exchange 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ć za pomocą metody getAccessToken:

$access_token = $client->getAccessToken();

Python

Na stronie wywołania zwrotnego użyj biblioteki google-auth, aby zweryfikować odpowiedź serwera autoryzacji. Następnie użyj metody flow.fetch_token, aby wymienić zawarty w niej kod autoryzacji 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/youtube.force-ssl'],
    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 użyj biblioteki googleauth, aby zweryfikować odpowiedź serwera autoryzacji. Użyj metody authorizer.handle_auth_callback_deferred, aby zapisać kod autoryzacji i przekierować z powrotem na adres URL, z którego pierwotnie zażądano autoryzacji. Opóźnia to wymianę 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.
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

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 z pierwszego żądania.
grant_type Zgodnie z definicją w specyfikacji protokołu OAuth 2.0 wartość tego pola musi być ustawiona na authorization_code.
redirect_uri Jeden z identyfikatorów URI przekierowania Twojego projektu w API Console Credentials page dla danego client_id.

Oto przykładowy fragment kodu:

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

W odpowiedzi na to żądanie Google zwraca obiekt JSON zawierający token dostępu o ograniczonym czasie ważności i token odświeżania. Pamiętaj, że token odświeżania jest zwracany tylko wtedy, gdy aplikacja ustawi parametr access_type na offline w pierwszym żądaniu wysyłanym do serwera autoryzacji Google.

Odpowiedź zawiera te pola:

Pola
access_token Token wysyłany przez aplikację do autoryzowania żądania do interfejsu API Google.
expires_in Pozostały czas ważności tokena dostępu (w sekundach).
refresh_token Token, którego możesz użyć do uzyskania nowego tokena dostępu. Tokeny odświeżania są ważne, dopóki użytkownik nie anuluje dostępu. To pole pojawia się w tej odpowiedzi tylko wtedy, gdy ustawisz wartość parametru access_type na offline w pierwszym żądaniu wysyłanym do serwera autoryzacji Google.
scope Zakresy dostępu przyznane przez funkcję access_token wyrażone jako lista ciągów tekstowych 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/youtube.force-ssl",
  "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
}

Błędy

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

invalid_grant

Podany kod autoryzacji jest nieprawidłowy lub ma nieprawidłowy format. Poproś o nowy kod przez ponowne uruchomienie procesu OAuth w celu ponownego poproszenia użytkownika o zgodę.

Wywoływanie interfejsów API Google

PHP

Aby wywołać interfejsy API Google, użyj tokena dostępu, wykonując te czynności:

  1. Aby zastosować token dostępu do nowego obiektu Google\Client (jeśli na przykład został on zapisany 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, udostępniając autoryzowany obiekt Google\Client konstruktorowi dla interfejsu API, który chcesz wywoływać. Aby na przykład wywołać interfejs YouTube Data API:
    $youtube = new Google_Service_YouTube($client);
  3. Wysyłaj żądania do usługi API za pomocą interfejsu udostępnianego przez obiekt usługi. Jeśli na przykład chcesz użyć interfejsu YouTube Data API do pobrania listy transmisji na żywo z kanału uwierzytelnionego użytkownika:
    $broadcasts = $youtube->liveBroadcasts->listLiveBroadcasts('id,snippet', [ 'mine' => true ]);

Python

Po uzyskaniu tokena dostępu aplikacja może używać go do autoryzowania żądań interfejsu API w imieniu danego konta użytkownika lub konta usługi. Za pomocą danych uwierzytelniających konkretnego użytkownika utwórz obiekt usługi dla interfejsu API, który chcesz wywoływać, a następnie użyj tego obiektu do 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 np. wywołać wersję 3 interfejsu YouTube Data API:
    from googleapiclient.discovery import build
    
    youtube = build('youtube', 'v3', credentials=credentials)
  2. Wysyłaj żądania do usługi API za pomocą interfejsu udostępnianego przez obiekt usługi. Jeśli na przykład chcesz użyć interfejsu YouTube Data API do pobrania listy transmisji na żywo z kanału uwierzytelnionego użytkownika:
    broadcasts = youtube.liveBroadcasts().list(part='id,snippet', mine=True).execute()

Ruby

Po uzyskaniu tokena dostępu aplikacja może używać go do wysyłania żądań do interfejsu API w imieniu danego konta użytkownika lub konta usługi. Za pomocą danych uwierzytelniających konkretnego użytkownika utwórz obiekt usługi dla interfejsu API, który chcesz wywoływać, a następnie użyj tego obiektu do 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 YouTube Data API:
    youtube = Google::Apis::YoutubeV3::YouTubeService.new
  2. Ustaw dane logowania w usłudze:
    youtube.authorization = credentials
  3. Wysyłaj żądania do usługi API za pomocą interfejsu udostępnianego przez obiekt usługi. Jeśli na przykład chcesz użyć interfejsu YouTube Data API do pobrania listy transmisji na żywo z kanału uwierzytelnionego użytkownika:
    broadcasts = youtube.list_liveBroadcasts('id,snippet', mine: true)

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

broadcasts = youtube.list_liveBroadcasts('id,snippet', mine: true)

Node.js

Po uzyskaniu tokena dostępu i ustawieniu go na obiekt OAuth2 użyj go 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ć, uwzględnij token dostępu w żądaniu wysyłanym do interfejsu API, podając parametr zapytania access_token lub wartość nagłówka HTTP Bearer Authorization. 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, aby skonfigurować wywołania interfejsów API Google (na przykład podczas wywoływania YouTube Live Streaming API).

Pamiętaj, że interfejs YouTube Live Streaming API nie obsługuje procesu konta usługi. Nie ma możliwości powiązania konta usługi z kontem YouTube, dlatego próby autoryzacji żądań za pomocą tego procesu spowodują wygenerowanie błędu NoLinkedYouTubeAccount.

Możesz wypróbować wszystkie interfejsy API Google i wyświetlić ich zakresy w interfejsie OAuth 2.0 Playground.

Przykłady żądań HTTP GET

Wywołanie punktu końcowego liveBroadcasts.list (YouTube Live Streaming API) przy użyciu nagłówka HTTP Authorization: Bearer może wyglądać tak. Pamiętaj, że musisz podać własny token dostępu:

GET /youtube/v3/liveBroadcasts?part=id%2Csnippet&mine=true 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/youtube/v3/liveBroadcasts?access_token=access_token&part=id%2Csnippet&mine=true

curl przykładu

Możesz je przetestować za pomocą aplikacji wiersza poleceń curl. Oto przykład z wykorzystaniem opcji nagłówka HTTP (preferowana):

curl -H "Authorization: Bearer access_token" https://www.googleapis.com/youtube/v3/liveBroadcasts?part=id%2Csnippet&mine=true

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

curl https://www.googleapis.com/youtube/v3/liveBroadcasts?access_token=access_token&part=id%2Csnippet&mine=true

Pełny przykład

Poniższy przykład drukuje obiekt w formacie JSON, który pokazuje transmisje na żywo z kanału YouTube uwierzytelnionego użytkownika po tym, jak użytkownik autoryzuje aplikację do pobierania tych danych.

PHP

Aby uruchomić ten przykład:

  1. W pliku API Consoledodaj adres URL komputera lokalnego do listy przekierowań, na przykład 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ższą treścią.
  5. Uruchom ten przykład z serwerem WWW skonfigurowanym do obsługi języka PHP. Jeśli używasz 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_YouTube::YOUTUBE_FORCE_SSL);

if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
  $client->setAccessToken($_SESSION['access_token']);
  $youtube = new Google_Service_YouTube($client);
  $broadcasts = $youtube->liveBroadcasts->listLiveBroadcasts('id,snippet', [ 'mine' => true ]);
  echo json_encode($broadcasts);
} 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_YouTube::YOUTUBE_FORCE_SSL);

if (! isset($_GET['code'])) {
  // Generate and set state value
  $state = bin2hex(random_bytes(16));
  $client->setState($state);
  $_SESSION['state'] = $state;

  $auth_url = $client->createAuthUrl();
  header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
} else {
  // Check the state value
  if (!isset($_GET['state']) || $_GET['state'] !== $_SESSION['state']) {
    die('State mismatch. Possible CSRF attack.');
  }
  $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. Uruchomi on aplikację internetową pod adresem http://localhost:8080, która umożliwia testowanie przepływu OAuth 2.0. Jeśli przejdziesz do tego adresu URL, powinny wyświetlić się 4 linki:

  • Testowanie żądania do interfejsu API: ten link wskazuje stronę, 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 przekierować użytkownika przez proces autoryzacji. Aplikacja prosi o uprawnienia do przesyłania autoryzowanych żądań do interfejsu API w imieniu użytkownika.
  • Unieważnij bieżące dane logowania: ten link prowadzi do strony, która anuluje uprawnienia przyznane aplikacji przez użytkownika.
  • Wyczyść dane uwierzytelniające sesji Flask: ten link czyści dane logowania, które są przechowywane w sesji Flask. Dzięki temu możesz zobaczyć, co by się stało, gdyby użytkownik, który przyznał już uprawnienia aplikacji, spróbował wykonać żądanie do interfejsu API w nowej sesji. Pozwala też zobaczyć odpowiedź interfejsu API, jaką otrzymałaby Twoja aplikacja, gdyby użytkownik unieważnił uprawnienia przyznane jej aplikacji, a aplikacja nadal próbowała autoryzować żądanie unieważnionym tokenem 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/youtube.force-ssl']
API_SERVICE_NAME = 'youtube'
API_VERSION = 'v3'

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

  youtube = googleapiclient.discovery.build(
      API_SERVICE_NAME, API_VERSION, credentials=credentials)

  broadcasts = youtube.liveBroadcasts().list(part='id,snippet', mine=True).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(**broadcasts)


@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/youtube_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
  youtube = Google::Apis::YoutubeV3::YouTubeService.new
  broadcasts = youtube.list_liveBroadcasts('id,snippet', mine: true)
  
  "<pre>#{JSON.pretty_generate(broadcasts.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 narzędziu API Consoledodaj adres URL komputera lokalnego do listy przekierowań, na przykład http://localhost.
  2. Sprawdź, czy masz zainstalowany kanał LTS do konserwacji, aktywny kanał LTS lub bieżącą 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ższą zawartością.
  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');
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 read-only Drive activity.
const scopes = [
  'https://www.googleapis.com/auth/drive.metadata.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 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;

      // 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
  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(80);
}
main().catch(console.error);

HTTP/REST

W tym przykładzie Pythona użyto platformy Flask i biblioteki Requests do zademonstrowania przepływu sieci opartego na protokole OAuth 2.0. W tym procesie zalecamy korzystanie z biblioteki klienta interfejsu API Google dla Pythona. (przykład na karcie Python korzysta z 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/youtube.force-ssl'
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://youtube.googleapis.com/youtube/v3/liveBroadcasts'
    r = requests.get(req_uri, headers=headers)
    return r.text


@app.route('/oauth2callback')
def oauth2callback():
  if 'code' not in flask.request.args:
    state = str(uuid.uuid4())
    flask.session['state'] = state
    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'}
    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

Google stosuje poniższe reguły weryfikacji do przekierowywania identyfikatorów URI. Ułatwia to deweloperom dbanie o bezpieczeństwo aplikacji. 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 standardu RFC 3986.

Reguły weryfikacji
Schemat

Identyfikatory URI przekierowania muszą korzystać ze schematu HTTPS, a nie zwykłego protokołu HTTP. Identyfikatory URI hosta lokalnego (w tym identyfikatory URI adresów IP hosta lokalnego) są wykluczone 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 TLD hostów (domeny najwyższego poziomu) muszą należeć do listy publicznych sufiksów.
  • Domeny hosta nie mogą być “googleusercontent.com”.
  • Identyfikatory URI przekierowania nie mogą zawierać domen skracających adresy URL (np. goo.gl), chyba że właścicielem domeny jest aplikacja. Ponadto jeśli aplikacja należąca do domeny skróconej przekierowuje do tej domeny, identyfikator URI przekierowania musi zawierać w ścieżce ciąg “/google-callback/” lub kończyć się ciągiem “/google-callback”.
  • Informacje o użytkowniku

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

    Ścieżka

    Identyfikatory URI przekierowania nie mogą zawierać przemierzania ścieżki (nazywanej też śledzeniem wstecznym katalogu), co jest reprezentowane przez “/..” lub “\..” bądź kodowanie ich adresów URL.

    Zapytanie

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

    Fragment

    Identyfikatory URI przekierowania nie mogą zawierać komponentu fragmentu.

    Znaki Identyfikatory URI przekierowań nie mogą zawierać niektórych znaków, w tym:
    • Symbole wieloznaczne ('*')
    • Znaki ASCII niedrukowalne
    • Nieprawidłowe kodowanie procentowe (dowolne kodowanie procentowe, które nie jest kodowane w postaci znaku procentu, po którym występują dwie cyfry szesnastkowe)
    • Znaki null (zakodowany znak NULL, np. %00, %C0%80)

    Autoryzacja przyrostowa

    W ramach protokołu OAuth 2.0 Twoja aplikacja żąda autoryzacji dostępu do zasobów określonych przez zakresy. Zalecamy wysyłanie próśb o autoryzację zasobów w chwili, gdy są potrzebne. Aby to umożliwić, serwer autoryzacji Google obsługuje autoryzację przyrostową. Ta funkcja umożliwia żądanie zakresów, a jeśli użytkownik przyzna uprawnienia do nowego zakresu, zwraca kod autoryzacji, który można wymienić na token zawierający wszystkie zakresy, które użytkownik przyznał projektowi.

    Załóżmy na przykład, że aplikacja pobiera dane z kanału YouTube uwierzytelnionego użytkownika i umożliwia mu pobieranie danych ze Statystyk YouTube za pomocą specjalnego procesu. W takim przypadku podczas logowania aplikacja może poprosić o dostęp tylko do zakresu https://www.googleapis.com/auth/youtube.force-ssl. Jeśli jednak użytkownik próbował uzyskać dostęp do danych Analytics dotyczących swojego kanału, aplikacja może również poprosić o dostęp do zakresu https://www.googleapis.com/auth/yt-analytics.readonly.

    Aby wdrożyć autoryzację przyrostową, musisz wykonać normalny proces żądania tokena dostępu, ale upewnij się, że żądanie autoryzacji obejmuje wcześniej przyznane zakresy. Dzięki temu aplikacja nie musi zarządzać wieloma tokenami dostępu.

    Te reguły mają zastosowanie do tokena dostępu uzyskanego z autoryzacji przyrostowej:

    • Token może służyć do uzyskiwania dostępu do zasobów odpowiadających dowolnym zakresom uwzględnionym w nowej, połączonej autoryzacji.
    • Gdy użyjesz tokena odświeżania do autoryzacji połączonej, aby uzyskać token dostępu, token dostępu reprezentuje połączoną autoryzację i może być używany dla dowolnej z wartości scope uwzględnionych w odpowiedzi.
    • Połączona autoryzacja obejmuje wszystkie zakresy, które użytkownik przyznał projektowi API, nawet jeśli prośby o zezwolenia pochodziły od różnych klientów. Jeśli na przykład użytkownik przyznał dostęp do jednego zakresu za pomocą klienta komputerowego aplikacji, a następnie przypisał inny zakres tej samej aplikacji za pomocą klienta mobilnego, połączona autoryzacja będzie obejmować oba zakresy.
    • Jeśli unieważnisz token, który reprezentuje łączną autoryzację, dostęp do wszystkich zakresów tej autoryzacji w imieniu powiązanego użytkownika zostanie jednocześnie anulowany.

    Przykłady kodu w zależności od języka z sekcji Krok 1. Ustaw parametry autoryzacji oraz przykładowy adres URL przekierowania HTTP/REST w kroku 2. Przekieruj na serwer OAuth 2.0 Google używają autoryzacji przyrostowej. Poniższe przykłady kodu zawierają również kod, który musisz dodać, aby użyć 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 zawiera wcześniej przyznane zakresy. Bardzo możliwe, że include_granted_scopes nie będzie ustawionym przez Ciebie argumentem słowa kluczowego only, 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

    W tym przykładzie aplikacja do wykonywania połączeń prosi o dostęp do pobierania danych użytkownika z YouTube oraz o dostęp do innych danych, które użytkownik przyznał aplikacji.

    GET https://accounts.google.com/o/oauth2/v2/auth?
      scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.force-ssl&
      access_type=offline&
      state=security_token%3D138rk%3Btarget_url%3Dhttp...index&
      redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback&
      response_type=code&
      client_id=client_id&
      include_granted_scopes=true
    
          

    Refreshing an access token (offline access)

    Access tokens periodically expire and become invalid credentials for a related API request. You can refresh an access token without prompting the user for permission (including when the user is not present) if you requested offline access to the scopes associated with the token.

    • If you use a Google API Client Library, the client object refreshes the access token as needed as long as you configure that object for offline access.
    • If you are not using a client library, you need to set the access_type HTTP query parameter to offline when redirecting the user to Google's OAuth 2.0 server. In that case, Google's authorization server returns a refresh token when you exchange an authorization code for an access token. Then, if the access token expires (or at any other time), you can use a refresh token to obtain a new access token.

    Requesting offline access is a requirement for any application that needs to access a Google API when the user is not present. For example, an app that performs backup services or executes actions at predetermined times needs to be able to refresh its access token when the user is not present. The default style of access is called online.

    Server-side web applications, installed applications, and devices all obtain refresh tokens during the authorization process. Refresh tokens are not typically used in client-side (JavaScript) web applications.

    PHP

    If your application needs offline access to a Google API, set the API client's access type to offline:

    $client->setAccessType("offline");

    Gdy użytkownik przyzna dostęp offline do żądanych zakresów, możesz nadal używać klienta interfejsu API do uzyskiwania dostępu do interfejsów API Google w jego imieniu, gdy jest on offline. W razie potrzeby obiekt klienta odświeży token dostępu.

    Python

    W Pythonie ustaw argument słowa kluczowego access_type na offline, aby mieć pewność, że będziesz mieć możliwość odświeżania tokena dostępu bez konieczności ponownego pytania użytkownika o uprawnienia. Bardzo możliwe, że access_type nie będzie jedynymustawionym przez Ciebie 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')

    Gdy użytkownik przyzna dostęp offline do żądanych zakresów, możesz nadal używać klienta interfejsu API do uzyskiwania dostępu do interfejsów API Google w jego imieniu, gdy jest on offline. W razie potrzeby obiekt klienta odświeży token dostępu.

    Ruby

    Jeśli Twoja aplikacja potrzebuje dostępu offline do interfejsu API Google, 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, możesz nadal używać klienta interfejsu API do uzyskiwania dostępu do interfejsów API Google w jego imieniu, gdy jest on offline. W razie potrzeby obiekt klienta odświeży token dostępu.

    Node.js

    Jeśli Twoja aplikacja potrzebuje dostępu offline do interfejsu API Google, 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, możesz nadal używać klienta interfejsu API do uzyskiwania dostępu do interfejsów API Google w jego imieniu, gdy jest on offline. W razie potrzeby obiekt klienta odświeży token dostępu.

    Tokeny dostępu wygasają. Ta biblioteka automatycznie użyje tokena odświeżania, aby uzyskać nowy token dostępu, jeśli wkrótce wygaśnie. Aby mieć pewność, że zawsze będziesz przechowywać 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 tokenów występuje tylko podczas pierwszej autoryzacji i musisz ustawić access_type na offline przy wywołaniu metody generateAuthUrl, aby otrzymać token odświeżania. Jeśli aplikacja ma już wymagane uprawnienia bez ustawionych odpowiednich ograniczeń umożliwiających otrzymywanie tokena odświeżania, musisz ponownie autoryzować aplikację, aby mogła otrzymać nowy token odświeżania.

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

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

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

    HTTP/REST

    Aby odświeżyć token dostępu, aplikacja wysyła do serwera autoryzacji Google (https://oauth2.googleapis.com/token) żądanie HTTPS POST, które zawiera 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 protokołu 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.

    Oto przykładowy fragment kodu:

    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

    Jeśli 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"
    }

    Pamiętaj, że w przypadku wszystkich klientów obowiązują limity liczby tokenów odświeżania: jeden limit na kombinację klienta/użytkownika, a drugi na użytkownika w przypadku wszystkich klientów. Tokeny odświeżania należy zapisać w pamięci długoterminowej i używać ich, dopóki są ważne. Jeśli aplikacja żąda zbyt wielu tokenów odświeżania, może przekroczyć te limity. W takim przypadku starsze tokeny odświeżania przestaną działać.

    Unieważnianie tokena

    W niektórych przypadkach użytkownik może cofnąć dostęp przyznany aplikacji. Użytkownik może anulować dostęp w Ustawieniach konta. Więcej informacji znajdziesz w artykule pomocy Usuwanie dostępu witryny lub aplikacji do Twojego konta.

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

    PHP

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

    $client->revokeToken();

    Python

    Aby automatycznie unieważnić token, wyślij żądanie do https://oauth2.googleapis.com/revoke, 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 błędów 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 błędów zwracany jest kod stanu 400 wraz z kodem błędu.

    HTTP/REST

    Aby automatycznie 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 będzie miał postać 200. W przypadku wystąpienia błędu zwracany jest kod stanu HTTP 400 wraz z kodem błędu.