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

po rozserwowaniu poszkodowania

System Google OAuth 2.0 obsługuje interakcję między serwerami, na przykład 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 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 czasem nazywany „dwutapową uwierzytelnianiem OAuth” lub „2LO”. Powiązany termin „trzyetapowa autoryzacja OAuth” odnosi się do sytuacji, w których aplikacja wywołuje interfejsy API Google w imieniu użytkowników, a w niektórych przypadkach wymagana jest zgoda użytkownika.

Zazwyczaj aplikacja korzysta z konta usługi, gdy używa interfejsów API Google do obsługi własnych danych, a nie danych użytkownika. Na przykład aplikacja, która używa Google Cloud Datastore do przechowywania danych, używa konta usługi do uwierzytelniania swoich wywołań interfejsu API Google Cloud Datastore.

Administratorzy domeny Google Workspace mogą też przyznawać kontu usługi uprawnienia w całej domenie w celu uzyskiwania dostępu do danych użytkowników w imieniu użytkowników w domenie.

Ten dokument opisuje, w jaki sposób aplikacja może zakończyć przepływ OAuth 2.0 między serwerami za pomocą biblioteki klienta interfejsów API Google (zalecane) lub HTTP.

Przegląd

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

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

Oprócz tego aplikacja może używać tokena dostępu do wywoływania interfejsów API Google.

Tworzę konto usługi

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

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

Jeśli aplikacja działa w Google Compute Engine, podczas tworzenia projektu konto usługi jest konfigurowane automatycznie, ale podczas tworzenia instancji Google Compute Engine musisz określić zakresy, do których aplikacja musi mieć dostęp. Więcej informacji znajdziesz w artykule Przygotowywanie instancji do korzystania z kont usługi.

Jeśli Twoja aplikacja nie działa w Google App Engine ani w Google Compute Engine, musisz uzyskać te dane w: Google API Console. Aby wygenerować dane logowania do konta usługi lub wyświetlić publiczne dane logowania, które zostały już wygenerowane:

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 publiczny/prywatny. Więcej informacji o danych logowania do konta usługi w API Consoleznajdziesz w sekcji Konta usługi w pliku pomocy API Console.

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

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

Za pomocą konta Google Workspace administrator organizacji może zezwolić aplikacji na dostęp 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 w celu uzyskania dostępu do interfejsu Google Calendar API w imieniu użytkowników. Przyznawanie kontu usługi uprawnień dostępu do danych w imieniu użytkowników w domenie jest czasami nazywane „przekazywaniem uprawnień w całej domenie” do konta usługi.

Aby delegować uprawnienia dostępu w całej domenie do konta usługi, superadministrator domeny Google Workspace musi wykonać te czynności:

  1. W konsoli administracyjnej domeny Google Workspace kliknij Menu główne > Zabezpieczenia > Dostęp do danych i kontrola nad nimi > Dostęp do interfejsów API.
  2. W panelu Przekazywanie dostępu w całej domenie kliknij 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 (rozdzielone przecinkami) wpisz listę zakresów, do których aplikacja ma mieć dostęp. Jeśli na przykład aplikacja potrzebuje pełnego dostępu do interfejsów API Dysku Google i Google Calendar API, wpisz: https://www.googleapis.com/auth/drive, https://www.googleapis.com/auth/calendar.
  6. Kliknij Autoryzuj.

Twoja aplikacja ma teraz uprawnienia do wywoływania interfejsu API jako użytkowników w Twojej domenie Workspace (czyli do podszywania się pod użytkowników). Przygotowując się do wywołania tych delegowanych interfejsów API, wyraźnie wskażesz użytkownika, pod który chcesz się podszywać.

Przygotowywanie wywołania interfejsu API

Java

Po otrzymaniu od klienta API Consoleadresu e-mail i klucza prywatnego skorzystaj z Biblioteki klienta interfejsów API Google dla języka Java, aby utworzyć obiekt GoogleCredential z 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, co może uprościć tę procedurę.

Przekazywanie uprawnień w całej domenie

Jeśli masz przekazany dostęp do konta usługi w całej domenie i chcesz odgrywać rolę konta użytkownika, określ adres e-mail tego konta, korzystając z metody createDelegated obiektu 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 wykorzystuje obiekt GoogleCredential do wywołania metody createDelegated(). Argument metody createDelegated() musi być użytkownikiem należącym do Twojego konta Workspace. Twój kod wysyłający żądanie będzie używać tych danych logowania do wywoływania interfejsów API Google przy użyciu Twojego konta usługi.

Python

Po otrzymaniu od klienta API Consoleadresu e-mail i klucza prywatnego skorzystaj z biblioteki klienta interfejsów API Google do języka Python, aby wykonać te czynności:

  1. Utwórz obiekt Credentials z danych logowania konta usługi i zakresów, do których Twoja aplikacja potrzebuje dostępu. Na 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, co może uprościć tę procedurę.

  2. Przekazywanie uprawnień w całej domenie

    Jeśli masz przekazany dostęp do konta usługi w całej domenie i chcesz podszyć się pod konto użytkownika, użyj metody with_subject istniejącego obiektu ServiceAccountCredentials. Na przykład:

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

Używaj obiektu danych logowania do wywoływania interfejsów API Google w swojej aplikacji.

HTTP/REST

Gdy uzyskasz identyfikator klienta i klucz prywatny z usługi API Console, Twoja aplikacja będzie musiała wykonać te czynności:

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

W sekcjach poniżej opisano, jak to zrobić.

Jeśli odpowiedź zawiera token dostępu, możesz użyć go do wywołania interfejsu API Google. (Jeśli odpowiedź nie zawiera tokena dostępu, żądanie tokena JWT i tokena może być nieprawidłowo utworzone 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 poprosi o kolejny.

Aplikacja serwera używa tokena JWT do żądania tokena z serwera autoryzacji Google, a następnie używa tego tokena do wywoływania punktu końcowego interfejsu API Google. Użytkownik nie jest w żaden sposób zaangażowany.

W pozostałej części tej sekcji opisano tworzenie tokena JWT, podpisywanie tokena JWT, tworzenie żądania tokena dostępu i obsługę odpowiedzi.

Tworzenie tokena JWT

Token JWT składa się z 3 części: nagłówka, zbioru roszczeń i podpisu. Nagłówek i zestaw roszczeń to obiekty JSON. Te obiekty JSON są zserializowane do bajtów UTF-8, a następnie kodowane za pomocą kodowania Base64url. Kodowanie zapewnia odporność na zmiany w kodowaniu spowodowane wielokrotnymi operacjami kodowania. Nagłówek, zestaw roszczeń i podpis są połączone kropką (.).

Token JWT wygląda tak:

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

Podstawowy ciąg podpisu:

{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ę wprowadzania kolejnych algorytmów i formatów ten nagłówek będzie się odpowiednio zmieniać. Identyfikator klucza jest opcjonalny. Jeśli podano nieprawidłowy identyfikator klucza, GCP spróbuje zweryfikować wszystkie klucze powiązane z kontem usługi, aby zweryfikować token i odrzucić token, jeśli nie zostanie on znaleziony. Google zastrzega sobie prawo do odrzucania w przyszłości tokenów z nieprawidłowymi identyfikatorami kluczy.

Konta usługi korzystają z algorytmu RSA SHA-256 i formatu tokena JWT. W związku z tym nagłówek pliku JSON wygląda tak:

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

Reprezentuje to taki kod Base64url:

          eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsICJraWQiOiIzNzBhYjc5YjQ1MTNlYjliYWQ3YzliZDE2YTk1Y2I3NmI1YjJhNTZhIn0=
Tworzenie zbioru roszczeń JWT

Zestaw deklaracji JWT zawiera informacje o tokenie JWT, w tym o żądanych uprawnieniach (zakresach), miejscu docelowym tokena, wydawcy, czasie jego przyznania oraz czasie jego ważności. Większość pól jest obowiązkowa. Podobnie jak nagłówek JWT, zbiór deklaracji JWT jest obiektem JSON i jest używany do obliczania podpisu.

Wymagane roszczenia

Poniżej znajdziesz wymagane roszczenia w zbiorze roszczeń JWT. Pojawiają się one w zestawie roszczeń w dowolnej kolejności.

Nazwa Opis
iss Adres e-mail konta usługi.
scope Lista rozdzielonych spacjami uprawnień, których żąda aplikacja.
aud Deskryptor zamierzonego asercji. W żądaniu tokena dostępu wartość zawsze wynosi https://oauth2.googleapis.com/token.
exp Czas wygaśnięcia potwierdzenia podany w sekundach od 00:00:00 czasu UTC, 1 stycznia 1970 roku. Wartość nie może być późniejsza niż godzina.
iat Godzina wysłania potwierdzenia podana jako sekundy od 00:00:00 czasu UTC, 1 stycznia 1970 roku.

Format JSON wymaganych pól w zbiorze deklaracji JWT jest pokazany poniżej:

{
  "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 aplikacje mogą używać przekazywania dostępu w całej domenie, aby działać w imieniu konkretnego użytkownika w organizacji. Zanim aplikacja może podszyć się pod użytkownika, musi zostać przyznana odpowiednie uprawnienie (i zwykle jest obsługiwana przez superadministratora). Więcej informacji znajdziesz w artykule Kontrola dostępu do interfejsu API przy użyciu przekazywania dostępu w całej domenie.

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

Nazwa Opis
sub Adres e-mail użytkownika, którego aplikacja żąda dostępu do konta.

Jeśli aplikacja nie ma uprawnień do odgrywania roli użytkownika, odpowiedź na żądanie tokena dostępu, które zawiera pole sub, będzie mieć błąd.

Poniżej znajdziesz przykładowy zestaw deklaracji JWT zawierający 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 zbioru deklaracji JWT

Podobnie jak nagłówek JWT, zestaw deklaracji JWT powinien być zserializowany za pomocą kodowania UTF-8 i Base64url bezpiecznych dla Base64url. Poniżej znajdziesz przykładowy kod JSON reprezentujący zestaw deklaracji JWT:

{
  "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 opisująca mechanizm generowania podpisu JWT. Dane wejściowe podpisu to bajtowa treść następującej zawartości:

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

Podczas obliczania podpisu należy użyć algorytmu podpisywania w nagłówku JWT. Jedynym algorytmem podpisywania obsługiwanym przez serwer autoryzacji Google OAuth 2.0 jest RSA z algorytmem szyfrowania SHA-256. Wartość ta jest wyrażana jako RS256 w polu alg w nagłówku JWT.

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

Podpis musi być zakodowany w standardzie Base64url. Nagłówek, zbiór roszczeń i podpis są łączone kropką (.). Efektem jest token JWT. Powinno być to:

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

Oto 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 znajduje się podpisany token JWT, który jest gotowy do przeniesienia:

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

Żądanie żądania tokena dostępu

Po wygenerowaniu podpisanego tokena JWT aplikacja może go użyć do żądania tokena dostępu. To żądanie tokena dostępu jest żądaniem HTTPS POST, a treść jest zakodowana. Adres URL jest widoczny poniżej:

https://oauth2.googleapis.com/token

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

Nazwa Opis
grant_type W razie potrzeby użyj tego ciągu zakodowanego w adresie URL: urn:ietf:params:oauth:grant-type:jwt-bearer
assertion Token JWT, w tym podpis.

Poniżej znajdziesz 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 to samo żądanie z użyciem właściwości 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 token JWT i token dostępu są poprawnie utworzone, a konto usługi ma uprawnienia do wykonania operacji, odpowiedź JSON z serwera autoryzacji 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 używać wielokrotnie w okresie ważności określonym przez wartość expires_in.

Wywoływanie interfejsów API Google

Java

Wykorzystaj obiekt GoogleCredential do wywoływania interfejsów API Google, wykonując te czynności:

  1. Utwórz obiekt usługi dla interfejsu API, który chcesz wywoływać przy użyciu obiektu GoogleCredential. Na przykład:
    SQLAdmin sqladmin =
        new SQLAdmin.Builder(httpTransport, JSON_FACTORY, credential).build();
  2. Wysyłanie żądań do usługi API za pomocą interfejsu udostępnianego przez obiekt usługi. Aby na przykład wyświetlić listę baz danych Cloud SQL w eksploracyjnym projekcie example-123:
    SQLAdmin.Instances.List instances =
        sqladmin.instances().list("exciting-example-123").execute();

Python

Aby wywołać Google API, użyj autoryzowanego obiektu Credentials:

  1. Utwórz obiekt usługi dla interfejsu API, który chcesz wywoływać. Obiekt usługi tworzysz przez wywołanie funkcji 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łanie żądań do usługi API za pomocą interfejsu udostępnianego przez obiekt usługi. Aby na przykład wyświetlić listę baz danych Cloud SQL w eksploracyjnym projekcie example-123:
    response = sqladmin.instances().list(project='exciting-example-123').execute()

HTTP/REST

Gdy aplikacja uzyska token dostępu, możesz go używać do wywoływania interfejsu Google API w imieniu danego konta usługi lub konta użytkownika, jeśli zostały przyznane zakresy dostępu wymagane przez ten interfejs. W tym celu umieść token dostępu w żądaniu wysyłanym do interfejsu API, dodając parametr zapytania access_token lub wartość nagłówka HTTP Authorization Bearer. Jeśli to możliwe, zalecamy użycie nagłówka HTTP, ponieważ ciągi zapytań są zwykle widoczne w dziennikach serwera. W większości przypadków wywołania biblioteki interfejsów API Google możesz skonfigurować na przykład za pomocą biblioteki klienta Drive API.

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

Przykłady HTTP GET

Wywołanie punktu końcowego drive.files (interfejsu Drive Files API) korzystającego z 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 je przetestować za pomocą aplikacji wiersza poleceń curl. Oto przykład użycia opcji nagłówka HTTP (preferowana):

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

Kiedy tokeny dostępu wygasną

Tokeny dostępu wydane przez serwer autoryzacji Google OAuth 2.0 wygasa po upływie czasu podanego przez wartość expires_in. Po wygaśnięciu tokena dostępu aplikacja powinna wygenerować kolejny token JWT, podpisać go i poprosić o kolejny token dostępu.

Kody błędów tokena JWT

Pole error Pole error_description Znaczenie Jak rozwiązać problem
unauthorized_client Unauthorized client or scope in request. Jeśli próbujesz użyć przekazywania dostępu w całej domenie, konto usługi nie ma autoryzacji 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 polu sub.

Choć zwykle zajmuje to kilka minut, rozpowszechnienie informacji na kontach wszystkich użytkowników na koncie Google 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 za pomocą adresu e-mail klienta, a nie identyfikatora klienta (liczbowego) w konsoli administracyjnej. Na stronie Przekazywanie dostępu w całej domenie w konsoli administracyjnej usuń klienta i dodaj go ponownie przy użyciu identyfikatora liczbowego.
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, w roszczeniu sub (pole), i że zawiera wszystkie zakresy, których dotyczy żądanie scope w Twoim tokenie JWT.

Choć zwykle zajmuje to kilka minut, rozpowszechnienie informacji na kontach wszystkich użytkowników na koncie Google może potrwać do 24 godzin.

admin_policy_enforced (dowolna wartość) Na koncie Google nie można autoryzować co najmniej 1 zakresu wymaganych przez zasady administratora Google Workspace.

Zapoznaj się z artykułem 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 ograniczyć dostęp do wszystkich zakresów lub poufnych i ograniczonych zakresów, dopóki nie zostanie wyraźnie przyznany identyfikator 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 prawidłowe roszczenia.

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

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

invalid_grant Not a valid email. Użytkownik nie istnieje. Sprawdź, czy adres e-mail podany w 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 czas lokalny jest nieprawidłowy. Może się to również zdarzyć, jeśli wartość exp jest późniejsza niż 65 minut od wartości iat albo wartość exp jest mniejsza niż wartość iat.

Upewnij się, że zegar w systemie, w którym generowany jest token JWT jest prawidłowy. W razie potrzeby zsynchronizuj czas z Google NTP.

invalid_grant Invalid JWT Signature.

Potwierdzenie tokena JWT jest podpisane kluczem prywatnym niepowiązanym z kontem usługi określonym w adresie e-mail klienta lub użyty klucz został usunięty, wyłączony lub wygasł.

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

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

Użyj biblioteki OAuth udostępnionej przez Google, aby upewnić się, że token JWT jest prawidłowo wygenerowany.

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 (tj. jest nieprawidłowy).

Sprawdź, czy pole scope (pole) tokena JWT jest wypełnione i porównaj zakresy zawarte w nim z udokumentowanymi zakresami interfejsów API, których chcesz używać. Dzięki temu zyskasz pewność, że nie ma w nich błędów ani literówek.

Pamiętaj, że lista zakresów w roszczeniu scope musi być oddzielona spacjami, a nie przecinkami.

disabled_client The OAuth client was disabled. Klucz używany do podpisywania potwierdzenia tokena 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 podpisywania 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 określonej organizacji Google Cloud.

Użyj konta usługi organizacji, aby uwierzytelnić. 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 okaziciela zamiast tokena dostępu OAuth 2.0. Jeśli to możliwe, przed wysłaniem wywołania interfejsu API nie musisz wysyłać żądania sieciowego do serwera autoryzacji Google.

Jeśli interfejs API, który chcesz wywołać, jest opublikowany w repozytorium GitHub interfejsów API Google, możesz wykonywać autoryzowane wywołania interfejsu API za pomocą tokena JWT, a nie tokena dostępu. Aby to zrobić:

  1. Utwórz konto usługi w sposób opisany powyżej. Pamiętaj, aby zachować plik JSON utworzony podczas tworzenia konta.
  2. Korzystając ze standardowej biblioteki JWT, takiej jak jwt.io, utwórz token JWT z nagłówkiem i ładunkiem w następujący sposób:
    {
      "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ść możesz znaleźć w polu private_key_id pliku JSON konta usługi.
    • W polach iss i sub podaj adres e-mail konta usługi. Tę wartość możesz znaleźć w polu client_email pliku JSON konta usługi.
    • W polu aud określ punkt końcowy interfejsu API. Na przykład: https://SERVICE.googleapis.com/.
    • W polu iat podaj bieżący czas systemu Unix, a w polu exp podaj czas dokładnie 3600 sekund, po którym token JWT wygaśnie.

Podpisz token JWT za pomocą RSA-256, używając klucza prywatnego w pliku JSON konta usługi.

Na przykład:

Java

Korzystanie z 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

Korzystanie z 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