Używanie protokołu OAuth 2.0 w aplikacjach międzyserwerowych

Zamiast Twojej Biblioteki klienta używasz tej usługi Usługę klienta używasz

System Google OAuth 2.0 obsługuje interakcje między serwerami, takie jak między aplikacją internetową a usługą Google. W tym scenariuszu potrzebujesz konta usługi, które należy do Twojej aplikacji, a nie do pojedynczego użytkownika końcowego. Twoja aplikacja wywołuje interfejsy API Google w imieniu konta usługi, więc użytkownicy nie są bezpośrednio zaangażowani. Ten scenariusz jest czasami nazywany „dwuetapową autoryzacją OAuth” lub „dwuetapową”. Pokrewne określenie „trzyetapowa autoryzacja OAuth” odnosi się do scenariuszy, w których aplikacja wywołuje interfejsy API Google w imieniu użytkowników i w których czasami wymagana jest zgoda użytkownika.

Zwykle aplikacja korzysta z konta usługi, gdy do pracy z własnymi danymi, a nie użytkownika, używane są interfejsy API Google. Na przykład aplikacja, która korzysta z Google Cloud Datastore, aby zapewnić trwałość danych, używa konta usługi do uwierzytelniania wywołań interfejsu Google Cloud Datastore API.

Administratorzy domeny Google Workspace mogą też przyznawać kontom usługi obowiązujące w całej domenie uprawnienia dostępu do danych użytkowników w imieniu użytkowników w tej domenie.

Ten dokument opisuje, jak aplikacja może zakończyć proces OAuth 2.0 między serwerami, korzystając z biblioteki klienta interfejsów API Google (zalecane) lub HTTP.

Opis

Aby obsługiwać interakcje między serwerami, najpierw utwórz konto usługi dla swojego projektu w zadaniu API Console. Jeśli chcesz uzyskać dostęp do danych użytkowników na swoim koncie Google Workspace, przyznaj dostęp do konta usługi w całej domenie.

Następnie aplikacja przygotowuje się do autoryzowanych wywołań interfejsu API przy użyciu danych logowania konta usługi w celu zażądania tokena dostępu z serwera uwierzytelniania OAuth 2.0.

Aplikacja może też używać tokena dostępu do wywoływania interfejsów API Google.

Tworzę konto usługi

Dane logowania konta usługi obejmują wygenerowany unikalny adres e-mail oraz co najmniej 1 parę kluczy (publiczny/prywatny). Jeśli jest włączone przekazywanie dostępu w całej domenie, identyfikator klienta też jest częścią danych logowania do konta usługi.

Jeśli Twoja aplikacja działa w Google App Engine, konto usługi zostanie skonfigurowane automatycznie podczas tworzenia projektu.

Jeśli Twoja aplikacja działa w Google Compute Engine, konto usługi jest też konfigurowane automatycznie podczas tworzenia projektu, ale podczas tworzenia instancji Google Compute Engine musisz określić zakresy, do których aplikacja potrzebuje dostępu. Więcej informacji znajdziesz w artykule o przygotowywaniu instancji do korzystania z kont usługi.

Jeśli Twoja aplikacja nie działa w Google App Engine ani Google Compute Engine, musisz uzyskać te dane logowania w Google API Console. Aby wygenerować dane logowania do konta usługi lub wyświetlić wygenerowane przez siebie publiczne dane logowania, wykonaj te czynności:

Najpierw utwórz konto usługi:

  1. Otwórz Service accounts page.
  2. If prompted, select a project, or create a new one.
  3. Kliknij Utwórz konto usługi .
  4. W obszarze Szczegóły konta usługi wpisz nazwę, identyfikator i opis konta usługi, a następnie kliknij Utwórz i kontynuuj .
  5. Opcjonalnie: w obszarze Przyznaj temu kontu usługi dostęp do projektu wybierz role uprawnień, które chcesz przyznać kontu usługi.
  6. Kliknij Kontynuuj .
  7. Opcjonalnie: w obszarze Przyznaj użytkownikom dostęp do tego konta usługi dodaj użytkowników lub grupy, które mogą używać konta usługi i zarządzać nim.
  8. Kliknij Gotowe .

Następnie utwórz klucz konta usługi:

  1. Kliknij adres e-mail utworzonego konta usługi.
  2. Kliknij kartę Klucze .
  3. Z listy rozwijanej Dodaj klucz wybierz opcję Utwórz nowy klucz .
  4. Kliknij Utwórz .

Twoja nowa para kluczy publiczny/prywatny jest generowana i pobierana na twój komputer; służy jako jedyna kopia klucza prywatnego. Jesteś odpowiedzialny za bezpieczne przechowywanie. Jeśli zgubisz tę parę kluczy, będziesz musiał wygenerować nową.

W każdej chwili możesz wrócić do API Console, aby wyświetlić adres e-mail, odciski cyfrowe klucza publicznego i inne informacje lub wygenerować dodatkowe pary kluczy publicznych/prywatnych. Więcej informacji o danych logowania do konta usługi w API Consoleznajdziesz w sekcji Konta usługi w pliku pomocy API Console.

Zapisz adres e-mail konta usługi i zapisz plik klucza prywatnego konta usługi w lokalizacji dostępnej dla Twojej aplikacji. Aplikacja potrzebuje ich do wykonywania autoryzowanych wywołań interfejsu API.

Przekazywanie do konta usługi uprawnień do całej domeny

Korzystając z konta Google Workspace, administrator Workspace w organizacji może autoryzować aplikację do uzyskiwania dostępu do danych użytkowników Workspace w imieniu użytkowników w domenie Google Workspace. Na przykład aplikacja, która używa interfejsu Google Calendar API do dodawania wydarzeń do kalendarzy wszystkich użytkowników w domenie Google Workspace, używa konta usługi, aby w imieniu użytkowników uzyskiwać dostęp do interfejsu Google Calendar API. Przyznawanie kontu usługi dostępu do danych w imieniu użytkowników w domenie jest czasem nazywane „przekazywaniem uprawnień w całej domenie” kontu usługi.

Aby przekazać kontu usługi uprawnienia obejmujące całą domenę, superadministrator domeny Google Workspace musi wykonać te czynności:

  1. W konsoli administracyjnej domeny Google Workspace otwórz menu główne > Zabezpieczenia > Dostęp do danych i kontrola nad nimi > Dostęp do interfejsów API.
  2. W okienku Przekazywanie dostępu w całej domenie wybierz Zarządzaj przekazywaniem dostępu w całej domenie.
  3. Kliknij Dodaj nowy.
  4. W polu Identyfikator klienta wpisz Identyfikator klienta konta usługi. Identyfikator klienta konta usługi znajdziesz w Service accounts page.
  5. W polu Zakresy OAuth (rozdzielane przecinkami) wpisz listę zakresów, do których aplikacja ma mieć dostęp. Jeśli na przykład Twoja aplikacja potrzebuje pełnego dostępu do interfejsów Google Drive API i Google Calendar API, wpisz: https://www.googleapis.com/auth/drive, https://www.googleapis.com/auth/calendar.
  6. Kliknij Autoryzuj.

Twoja aplikacja może teraz wykonywać wywołania interfejsu API jako użytkownicy w domenie Workspace (aby odgrywać rolę użytkowników). Przygotowując się do wykonania tych wywołań interfejsu API, musisz wyraźnie wskazać użytkownika, którego rolę będzie odgrywać.

Przygotowuję wywołanie delegowanego interfejsu API

Java

Gdy uzyskasz adres e-mail klienta i klucz prywatny z API Console, użyj biblioteki klienta interfejsów API Google dla języka Java, aby utworzyć obiekt GoogleCredential na podstawie danych logowania konta usługi i zakresów, do których aplikacja potrzebuje dostępu. Na przykład:

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.services.sqladmin.SQLAdminScopes;

// ...

GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"))
    .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN));

Jeśli tworzysz aplikację w Google Cloud Platform, możesz użyć domyślnych danych logowania aplikacji, aby uprościć ten proces.

Przekazywanie uprawnień do całej domeny

Jeśli przekażesz do konta usługi dostęp w całej domenie i chcesz odgrywać rolę konta użytkownika, podaj adres e-mail konta użytkownika za pomocą metody createDelegated w obiekcie GoogleCredential. Na przykład:

GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"))
    .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN))
    .createDelegated("workspace-user@example.com");

Powyższy kod używa obiektu GoogleCredential do wywoływania swojej metody createDelegated(). Argumentem metody createDelegated() musi być użytkownik, który należy do Twojego konta Workspace. Twój kod tworzący żądanie użyje tych danych logowania do wywoływania interfejsów API Google przy użyciu Twojego konta usługi.

Python

Gdy uzyskasz adres e-mail klienta i klucz prywatny z API Console, użyj biblioteki klienta interfejsów API Google dla języka Python, aby wykonać te czynności:

  1. Utwórz obiekt Credentials na podstawie danych logowania konta usługi i zakresów, do których aplikacja potrzebuje dostępu. Przykład:
    from google.oauth2 import service_account
    
    SCOPES = ['https://www.googleapis.com/auth/sqlservice.admin']
    SERVICE_ACCOUNT_FILE = '/path/to/service.json'
    
    credentials = service_account.Credentials.from_service_account_file(
            SERVICE_ACCOUNT_FILE, scopes=SCOPES)

    Jeśli tworzysz aplikację w Google Cloud Platform, możesz użyć domyślnych danych logowania aplikacji, aby uprościć ten proces.

  2. Przekazywanie uprawnień do całej domeny

    Jeśli przekazałeś dostęp do konta usługi w całej domenie i chcesz odgrywać rolę konta użytkownika, użyj metody with_subject istniejącego obiektu ServiceAccountCredentials. Na przykład:

    delegated_credentials = credentials.with_subject('user@example.org')

Użyj obiektu danych logowania, aby wywołać interfejsy API Google w swojej aplikacji.

HTTP/REST

Gdy uzyskasz identyfikator klienta i klucz prywatny z API Console, aplikacja musi wykonać te czynności:

  1. Utwórz token sieciowy JSON (JWT, wymawianego jako „jot”), który zawiera nagłówek, zestaw deklaracji i podpis.
  2. Poproś o token dostępu z serwera autoryzacji Google OAuth 2.0.
  3. Przetwórz odpowiedź JSON zwracaną przez serwer autoryzacji.

Poniżej opisujemy, jak wykonać te czynności.

Jeśli odpowiedź zawiera token dostępu, możesz za jego pomocą wywołać interfejs Google API. (Jeśli odpowiedź nie zawiera tokena dostępu, żądanie JWT i tokena może mieć nieprawidłowy format lub konto usługi może nie mieć uprawnień dostępu do żądanych zakresów).

Gdy token dostępu wygaśnie, aplikacja wygeneruje kolejny token JWT, podpisze go i zażąda innego tokena dostępu.

Aplikacja serwera używa tokena JWT, aby zażądać tokena z serwera autoryzacji Google, a następnie używa tego tokena do wywołania punktu końcowego interfejsu Google API. Nie dotyczy to żadnego użytkownika.

W dalszej części tej sekcji znajdziesz szczegółowe informacje na temat tworzenia tokena JWT, podpisywania JWT, tworzenia żądania tokena dostępu i obsługi odpowiedzi.

Tworzenie tokena JWT

Token JWT składa się z 3 części: nagłówka, zbioru deklaracji i podpisu. Nagłówek i zestaw deklaracji są obiektami JSON. Te obiekty JSON są zserializowane do formatu UTF-8, a następnie kodowane z użyciem kodowania Base64url. To kodowanie zapewnia odporność na zmiany w kodowaniu wynikające z powtarzanych operacji. Nagłówek, zestaw deklaracji i podpis są połączone znakiem kropki (.).

Token JWT ma się tak:

{Base64url encoded header}.{Base64url encoded claim set}.{Base64url encoded signature}

Ciąg bazowy podpisu jest następujący:

{Base64url encoded header}.{Base64url encoded claim set}
Tworzenie nagłówka JWT

Nagłówek składa się z 3 pól wskazujących algorytm podpisywania, format potwierdzenia i [identyfikator klucza klucza konta usługi](https://cloud.google.com/iam/docs/reference/rest/v1/projects.serviceAccounts.keys), który został użyty do podpisania tokena JWT. Algorytm i format są wymagane, a każde pole ma tylko jedną wartość. W miarę wprowadzenia kolejnych algorytmów i formatów ten nagłówek będzie się odpowiednio zmieniać. Identyfikator klucza jest opcjonalny. Jeśli zostanie podany nieprawidłowy identyfikator, GCP spróbuje sprawdzić wszystkie klucze powiązane z kontem usługi, aby zweryfikować token. Jeśli nie znajdzie prawidłowego klucza, odrzuci token. Google zastrzega sobie prawo do odrzucenia tokenów z nieprawidłowymi identyfikatorami w przyszłości.

Konta usługi korzystają z algorytmu RSA SHA-256 i formatu tokena JWT. W związku z tym nagłówek ma postać JSON:

{"alg":"RS256","typ":"JWT", "kid":"370ab79b4513eb9bad7c9bd16a95cb76b5b2a56a"}

Zmienna Base64url wygląda tak:

          eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsICJraWQiOiIzNzBhYjc5YjQ1MTNlYjliYWQ3YzliZDE2YTk1Y2I3NmI1YjJhNTZhIn0=
Tworzenie zestawu deklaracji JWT

Zestaw deklaracji JWT zawiera informacje o tokenie JWT, w tym żądane uprawnienia (zakresy), miejsce docelowe tokena, wydawca, czas wystawienia tokena i jego czas życia. Większość pól jest obowiązkowa. Podobnie jak nagłówek JWT, zestaw deklaracji JWT jest obiektem JSON i jest używany do obliczania podpisu.

Wymagane roszczenia

Poniżej znajdziesz wymagane deklaracje w zestawie deklaracji JWT. Mogą występować w dowolnej kolejności w zestawie roszczeń.

Nazwa Opis
iss Adres e-mail konta usługi.
scope Lista rozdzielonych spacjami uprawnień, których żąda aplikacja.
aud Deskryptor docelowego elementu asercji. Gdy tworzysz żądanie tokena dostępu, ta wartość zawsze wynosi https://oauth2.googleapis.com/token.
exp Czas wygaśnięcia potwierdzenia określony jako sekundy od godziny 00:00:00 czasu UTC, 1 stycznia 1970 roku. Ta wartość może przypadać maksymalnie 1 godzinę po wystawieniu.
iat Godzina wykonania potwierdzenia podana w sekundach od 00:00:00 czasu UTC, 1 stycznia 1970 roku.

Oto reprezentacja wymaganych pól w zbiorze deklaracji JWT w formacie JSON:

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "scope": "https://www.googleapis.com/auth/devstorage.read_only",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
Dodatkowe roszczenia

W niektórych przypadkach aplikacja może korzystać z przekazywania dostępu w całej domenie do działania w imieniu konkretnego użytkownika w organizacji. Aby aplikacja mogła odgrywać rolę użytkownika, musisz przyznać aplikacji uprawnienia do podszywania się pod inne osoby. Zwykle obsługuje je superadministrator. Więcej informacji znajdziesz w artykule o kontrolowaniu dostępu do interfejsów API przy użyciu przekazywania dostępu w całej domenie.

Aby uzyskać token dostępu, który przyznaje aplikacji przekazywanie dostępu do zasobu, podaj adres e-mail użytkownika w deklaracji JWT jako wartość pola sub.

Nazwa Opis
sub Adres e-mail użytkownika, w przypadku którego aplikacja prosi o przekazanie dostępu.

Jeśli aplikacja nie ma uprawnień do odgrywania roli użytkownika, odpowiedź na żądanie tokena dostępu zawierające pole sub będzie błędem.

Poniżej znajduje się przykład deklaracji JWT, która zawiera pole sub:

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "sub": "some.user@example.com",
  "scope": "https://www.googleapis.com/auth/prediction",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
Kodowanie zestawu deklaracji JWT

Podobnie jak nagłówek JWT, zestaw deklaracji JWT powinien być zserializowany do UTF-8 i zakodowany w Base64url. Poniżej znajdziesz przykład reprezentacji zbioru deklaracji JWT w formacie JSON:

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "scope": "https://www.googleapis.com/auth/prediction",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
Obliczanie podpisu

Podpis internetowy JSON (JWS) to specyfikacja, która określa mechanikę generowania podpisu dla tokena JWT. Dane wejściowe podpisu to tablica bajtowa tej treści:

{Base64url encoded header}.{Base64url encoded claim set}

Podczas przetwarzania podpisu należy używać algorytmu podpisywania w nagłówku JWT. Jedynym algorytmem podpisywania obsługiwanym przez serwer autoryzacji Google OAuth 2.0 jest RSA używająca algorytmu szyfrowania SHA-256. Ta wartość jest wyrażona jako RS256 w polu alg w nagłówku JWT.

Podpisz dane wejściowe w formacie UTF-8 za pomocą algorytmu SHA256withRSA (znanego też jako RSASSA-PKCS1-V1_5-SIGN z funkcją skrótu SHA-256) kluczem prywatnym uzyskanym z Google API Console. Wynikiem będzie tablica bajtowa.

Podpis musi być zakodowany w formacie Base64url. Nagłówek, zestaw deklaracji i podpis są połączone znakiem kropki (.). Wynik to token JWT. Powinien on wyglądać tak (aby było bardziej przejrzyste):

{Base64url encoded header}.
{Base64url encoded claim set}.
{Base64url encoded signature}

Poniżej znajdziesz przykład tokena JWT przed kodowaniem Base64url:

{"alg":"RS256","typ":"JWT"}.
{
"iss":"761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
"scope":"https://www.googleapis.com/auth/prediction",
"aud":"https://oauth2.googleapis.com/token",
"exp":1328554385,
"iat":1328550785
}.
[signature bytes]

Poniżej znajdziesz przykład tokena JWT, który został podpisany i jest gotowy do przesłania:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL29hdXRoMi92NC90b2tlbiIsImV4cCI6MTMyODU1NDM4NSwiaWF0IjoxMzI4NTUwNzg1fQ.UFUt59SUM2_AW4cRU8Y0BYVQsNTo4n7AFsNrqOpYiICDu37vVt-tw38UKzjmUKtcRsLLjrR3gFW3dNDMx_pL9DVjgVHDdYirtrCekUHOYoa1CMR66nxep5q5cBQ4y4u2kIgSvChCTc9pmLLNoIem-ruCecAJYgI9Ks7pTnW1gkOKs0x3YpiLpzplVHAkkHztaXiJdtpBcY1OXyo6jTQCa3Lk2Q3va1dPkh_d--GU2M5flgd8xNBPYw4vxyt0mP59XZlHMpztZt0soSgObf7G3GXArreF_6tpbFsS3z2t5zkEiHuWJXpzcYr5zWTRPDEHsejeBSG8EgpLDce2380ROQ

Wysyłanie żądania tokena dostępu

Po wygenerowaniu podpisanego tokena JWT aplikacja może go użyć, aby zażądać tokena dostępu. To żądanie tokena dostępu to żądanie HTTPS POST, a treść jest zakodowana na potrzeby adresu URL. Adres URL jest widoczny poniżej:

https://oauth2.googleapis.com/token

W żądaniu HTTPS POST wymagane są te parametry:

Nazwa Opis
grant_type Użyj tego ciągu znaków (w razie potrzeby zakodowanego w adresie URL):urn:ietf:params:oauth:grant-type:jwt-bearer
assertion Token JWT wraz z podpisem.

Poniżej znajduje się nieprzetworzony zrzut żądania HTTPS POST używanego w żądaniu tokena dostępu:

POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU3MzM4MSwiaWF0IjoxMzI4NTY5NzgxfQ.ixOUGehweEVX_UKXv5BbbwVEdcz6AYS-6uQV6fGorGKrHf3LIJnyREw9evE-gs2bmMaQI5_UbabvI4k-mQE4kBqtmSpTzxYBL1TCd7Kv5nTZoUC1CmwmWCFqT9RE6D7XSgPUh_jF1qskLa2w0rxMSjwruNKbysgRNctZPln7cqQ

Poniżej znajduje się to samo żądanie z użyciem parametru curl:

curl -d 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU3MzM4MSwiaWF0IjoxMzI4NTY5NzgxfQ.RZVpzWygMLuL-n3GwjW1_yhQhrqDacyvaXkuf8HcJl8EtXYjGjMaW5oiM5cgAaIorrqgYlp4DPF_GuncFqg9uDZrx7pMmCZ_yHfxhSCXru3gbXrZvAIicNQZMFxrEEn4REVuq7DjkTMyCMGCY1dpMa8aWfTQFt3Eh7smLchaZsU
' https://oauth2.googleapis.com/token

Obsługa odpowiedzi

Jeśli żądanie tokena JWT i tokena dostępu ma prawidłowy format, a konto usługi ma uprawnienia do wykonania tej operacji, odpowiedź JSON z serwera autoryzacji będzie zawierać token dostępu. Oto przykładowa odpowiedź:

{
  "access_token": "1/8xbJqaOZXSUZbHLl5EOtu1pxz3fmmetKx9W8CV4t79M",
  "scope": "https://www.googleapis.com/auth/prediction"
  "token_type": "Bearer",
  "expires_in": 3600
}

Tokenów dostępu można ponownie używać w okresie trwania określonym przez wartość expires_in.

Wywoływanie interfejsów API Google

Java

Za pomocą obiektu GoogleCredential możesz wywoływać interfejsy API Google, wykonując te czynności:

  1. Utwórz obiekt usługi dla interfejsu API, który chcesz wywoływać za pomocą obiektu GoogleCredential. Na przykład:
    SQLAdmin sqladmin =
        new SQLAdmin.Builder(httpTransport, JSON_FACTORY, credential).build();
  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ę instancji baz danych Cloud SQL w projekcie Ekscytujący-example-123:
    SQLAdmin.Instances.List instances =
        sqladmin.instances().list("exciting-example-123").execute();

Python

Do wywoływania interfejsów API Google użyj autoryzowanego obiektu Credentials, wykonując te czynności:

  1. Utwórz obiekt usługi dla interfejsu API, który chcesz wywoływać. Obiekt usługi tworzysz, wywołując funkcję build z nazwą i wersją interfejsu API oraz autoryzowanym obiektem Credentials. Aby na przykład wywołać wersję 1beta3 interfejsu Cloud SQL Administration API:
    import googleapiclient.discovery
    
    sqladmin = googleapiclient.discovery.build('sqladmin', 'v1beta3', 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ę instancji baz danych Cloud SQL w projekcie Ekscytujący-example-123:
    response = sqladmin.instances().list(project='exciting-example-123').execute()

HTTP/REST

Gdy aplikacja uzyska token dostępu, możesz za jego pomocą wywoływać interfejs API Google w imieniu danego konta usługi lub 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

Po wygaśnięciu tokenów dostępu

Tokeny dostępu wystawione przez serwer autoryzacji Google OAuth 2.0 tracą ważność po czasie określonym przez wartość expires_in. Gdy token dostępu wygaśnie, aplikacja powinna wygenerować kolejny token JWT, podpisać go i zażądać innego tokena dostępu.

Kody błędów JWT

Pole error Pole error_description Znaczenie Jak rozwiązać ten problem
unauthorized_client Unauthorized client or scope in request. Jeśli chcesz przekazać dostęp w całej domenie, konto usługi nie jest autoryzowane w konsoli administracyjnej domeny użytkownika.

Sprawdź, czy konto usługi jest autoryzowane na stronie Przekazywanie dostępu w całej domenie w konsoli administracyjnej użytkownika w zadeklarowaniu własności sub.

Chociaż zwykle trwa to kilka minut, rozpowszechnienie autoryzacji na wszystkie konta Google użytkowników może potrwać do 24 godzin.

unauthorized_client Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested. Konto usługi zostało autoryzowane w konsoli administracyjnej przy użyciu adresu e-mail klienta, a nie identyfikatora klienta (liczbowego). Na stronie Przekazywanie dostępu w całej domenie w konsoli administracyjnej usuń klienta i dodaj go ponownie z identyfikatorem liczbowym.
access_denied (dowolna wartość) Jeśli korzystasz z przekazywania dostępu w całej domenie, co najmniej jeden z żądanych zakresów nie jest autoryzowany w konsoli administracyjnej.

Sprawdź, czy konto usługi jest autoryzowane na stronie Przekazywanie dostępu w całej domenie w konsoli administracyjnej użytkownika zadeklarowanego w zadeklarowaniu sub (pole usługi) i czy zawiera ono wszystkie zakresy, o które prosisz w żądaniu scope tokena JWT.

Chociaż zwykle trwa to kilka minut, rozpowszechnienie autoryzacji na wszystkie konta Google użytkowników może potrwać do 24 godzin.

admin_policy_enforced (dowolna wartość) 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.

invalid_client (dowolna wartość)

Klient OAuth lub token JWT jest nieprawidłowy lub nieprawidłowo skonfigurowany.

Szczegółowe informacje znajdziesz w opisie błędu.

Sprawdź, czy token JWT jest prawidłowy i zawiera poprawne deklaracje.

Sprawdź, czy klient i konto usługi OAuth są prawidłowo skonfigurowane i czy używasz prawidłowego adresu e-mail.

Sprawdź, czy token JWT jest prawidłowy i został wystawiony dla identyfikatora klienta w żądaniu.

invalid_grant Not a valid email. Użytkownik nie istnieje. Sprawdź, czy adres e-mail w roszczeniu (polu) sub jest prawidłowy.
invalid_grant

Invalid JWT: Token must be a short-lived token (60 minutes) and in a reasonable timeframe. Check your 'iat' and 'exp' values and use a clock with skew to account for clock differences between systems.

Zwykle oznacza to, że lokalny czas systemowy jest nieprawidłowy. Może się tak również zdarzyć, jeśli wartość exp wybiega o ponad 65 minut w przyszłości od wartości iat lub gdy wartość exp jest niższa niż wartość iat.

Sprawdź, czy zegar w systemie, w którym generowany jest token JWT, jest prawidłowy. W razie potrzeby zsynchronizuj czas z NTP Google.

invalid_grant Invalid JWT Signature.

Potwierdzenie JWT jest podpisane kluczem prywatnym niepowiązanym z kontem usługi wskazanym przez adres e-mail klienta lub użyty klucz został usunięty, wyłączony lub wygasł.

Możliwe też, że potwierdzenie JWT może być nieprawidłowo zakodowane – musi być zakodowane w Base64, bez znaków nowego wiersza i znaków równości.

Zdekoduj zestaw deklaracji JWT i sprawdź klucz, który podpisał potwierdzenie, jest powiązany z kontem usługi.

Użyj biblioteki OAuth udostępnionej przez Google, aby mieć pewność, że token JWT został wygenerowany prawidłowo.

invalid_scope Invalid OAuth scope or ID token audience provided. Nie zażądano żadnych zakresów (pusta lista zakresów) lub jeden z żądanych zakresów nie istnieje (tzn. jest nieprawidłowy).

Sprawdź, czy pole żądania scope tokena JWT jest wypełnione, i porównaj zawarte w nim zakresy z udokumentowanymi zakresami interfejsów API, których chcesz użyć, aby upewnić się, że nie ma błędów ani literówek.

Pamiętaj, że lista zakresów w żądaniu scope musi być rozdzielona spacjami, a nie przecinkami.

disabled_client The OAuth client was disabled. Klucz używany do podpisywania potwierdzenia JWT jest wyłączony.

Otwórz Google API Consolei w sekcji Administracja > Konta usługi włącz konto usługi zawierające „identyfikator klucza” używany do podpisania potwierdzenia.

org_internal This client is restricted to users within its organization. Identyfikator klienta OAuth w żądaniu jest częścią projektu ograniczającego dostęp do kont Google w konkretnej organizacji Google Cloud.

Do uwierzytelnienia użyj konta usługi organizacji. Potwierdź konfigurację typu użytkownika dla aplikacji OAuth.

Załącznik: autoryzacja konta usługi bez protokołu OAuth

W przypadku niektórych interfejsów API Google możesz wykonywać autoryzowane wywołania interfejsu API, używając podpisanego tokena JWT bezpośrednio jako tokena okaziciela zamiast tokena dostępu OAuth 2.0. Jeśli to możliwe, unikasz konieczności wysyłania żądania sieciowego do serwera autoryzacji Google przed wywołaniem interfejsu API.

Jeśli interfejs API, który chcesz wywołać, ma definicję usługi opublikowaną w repozytorium interfejsów API Google na GitHubie, możesz wykonać autoryzowane wywołania interfejsu API za pomocą tokena JWT zamiast tokena dostępu. Aby to zrobić:

  1. Utwórz konto usługi w sposób opisany powyżej. Zachowaj plik JSON otrzymany podczas tworzenia konta.
  2. Użyj dowolnej standardowej biblioteki JWT, np. biblioteki jwt.io, utwórz token JWT z nagłówkiem i ładunkiem, jak w tym przykładzie:
    {
      "alg": "RS256",
      "typ": "JWT",
      "kid": "abcdef1234567890"
    }
    .
    {
      "iss": "123456-compute@developer.gserviceaccount.com",
      "sub": "123456-compute@developer.gserviceaccount.com",
      "aud": "https://firestore.googleapis.com/",
      "iat": 1511900000,
      "exp": 1511903600
    }
    • W polu kid w nagłówku podaj identyfikator klucza prywatnego konta usługi. Tę wartość znajdziesz w polu private_key_id pliku JSON konta usługi.
    • W polach iss i sub wpisz adres e-mail konta usługi. Tę wartość znajdziesz w polu client_email pliku JSON konta usługi.
    • W polu aud podaj punkt końcowy API. Na przykład: https://SERVICE.googleapis.com/.
    • W polu iat podaj bieżący czas uniksowy, a w polu exp – czas dokładnie 3600 sekund później, kiedy token JWT wygaśnie.

Podpisz token JWT za pomocą RSA-256 za pomocą klucza prywatnego, który znajduje się w pliku JSON konta usługi.

Na przykład:

Java

Korzystanie z plików google-api-java-client i java-jwt:

GoogleCredential credential =
        GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"));
PrivateKey privateKey = credential.getServiceAccountPrivateKey();
String privateKeyId = credential.getServiceAccountPrivateKeyId();

long now = System.currentTimeMillis();

try {
    Algorithm algorithm = Algorithm.RSA256(null, privateKey);
    String signedJwt = JWT.create()
        .withKeyId(privateKeyId)
        .withIssuer("123456-compute@developer.gserviceaccount.com")
        .withSubject("123456-compute@developer.gserviceaccount.com")
        .withAudience("https://firestore.googleapis.com/")
        .withIssuedAt(new Date(now))
        .withExpiresAt(new Date(now + 3600 * 1000L))
        .sign(algorithm);
} catch ...

Python

Za pomocą PyJWT:

iat = time.time()
exp = iat + 3600
payload = {'iss': '123456-compute@developer.gserviceaccount.com',
           'sub': '123456-compute@developer.gserviceaccount.com',
           'aud': 'https://firestore.googleapis.com/',
           'iat': iat,
           'exp': exp}
additional_headers = {'kid': PRIVATE_KEY_ID_FROM_JSON}
signed_jwt = jwt.encode(payload, PRIVATE_KEY_FROM_JSON, headers=additional_headers,
                       algorithm='RS256')
  1. Wywołaj interfejs API, używając podpisanego tokena JWT jako tokena okaziciela:
    GET /v1/projects/abc/databases/123/indexes HTTP/1.1
    Authorization: Bearer SIGNED_JWT
    Host: firestore.googleapis.com