OAuth 2.0 dla aplikacji internetowych po stronie klienta

Zadbaj o dobrą organizację dzięki kolekcji Zapisuj i kategoryzuj treści zgodnie ze swoimi preferencjami.

Ten dokument wyjaśnia, jak wdrożyć autoryzację OAuth 2.0 do korzystania z interfejsów API Google przez aplikację internetową JavaScript. Protokół OAuth 2.0 umożliwia użytkownikom udostępnianie określonych danych aplikacji przy jednoczesnym zachowaniu nazw użytkowników, haseł i innych informacji. Aplikacja może na przykład używać protokołu OAuth 2.0 w celu uzyskania zgody od użytkowników na przechowywanie plików na ich Dyskach Google.

Taki przepływ protokołu OAuth 2.0 jest nazywany procesem przyznania dostępu. Jest ona przeznaczona dla aplikacji, które korzystają z interfejsów API tylko wtedy, gdy użytkownik korzysta z aplikacji. Te aplikacje nie mogą przechowywać informacji poufnych.

W ramach tego procesu aplikacja otwiera adres URL Google, który używa parametrów zapytania do identyfikowania aplikacji i typu dostępu API, którego wymaga aplikacja. Możesz otworzyć adres URL w bieżącym oknie przeglądarki lub w wyskakującym okienku. Użytkownik może uwierzytelnić się w Google i przyznać mu wymagane uprawnienia. Następnie Google przekierowuje użytkownika z powrotem do Twojej aplikacji. Przekierowanie zawiera token dostępu, który aplikacja weryfikuje, a potem używa do wysyłania żądań do interfejsu API.

Wymagania wstępne

Włączanie interfejsów API w projekcie

Każda aplikacja, która wywołuje interfejsy API Google, musi włączyć te interfejsy API 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. Na liście API Library znajdują się wszystkie dostępne interfejsy API, pogrupowane według rodziny usług i popularności. Jeśli na liście nie widzisz interfejsu API, który chcesz włączyć, wyszukaj go lub kliknij Wyświetl wszystkie w grupie usług, do której należy.
  4. Wybierz interfejs API, który chcesz włączyć, a następnie kliknij przycisk Włącz.
  5. If prompted, enable billing.
  6. If prompted, read and accept the API's Terms of Service.

Tworzenie danych logowania

Każda aplikacja korzystająca z interfejsu OAuth 2.0, która ma dostęp do interfejsów API Google, musi mieć dane logowania, które identyfikują aplikację na serwerze OAuth 2.0 Google. Aby utworzyć dane logowania do projektu, wykonaj opisane poniżej czynności. Twoje aplikacje będą mogły używać danych logowania do 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. Wybierz typ aplikacji Aplikacja internetowa.
  4. Wypełnij formularz. Aplikacje używające JavaScriptu do wykonywania autoryzowanych żądań do interfejsu API Google muszą określać autoryzowane źródła kodu JavaScript. Źródła identyfikujące domeny, z których aplikacja może wysyłać żądania do serwera OAuth 2.0. Te źródła muszą być zgodne z regułami weryfikacji Google.

Zakresy dostępu

Zakresy umożliwiają aplikacji żądanie tylko dostępu do potrzebnych zasobów, a jednocześnie umożliwienie użytkownikom kontrolowania poziomu dostępu przyznanego aplikacji. Dlatego może występować odwrotna zależność między liczbą żądanych zakresów a prawdopodobieństwem uzyskania zgody użytkownika.

Przed rozpoczęciem autoryzacji OAuth 2.0 zalecamy określenie zakresów, do których aplikacja będzie potrzebować dostępu.

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

Uzyskiwanie tokenów dostępu OAuth 2.0

Poniżej znajdziesz sposób interakcji aplikacji z serwerem Google OAuth 2.0 w celu uzyskania zgody użytkownika na wykonanie żądania interfejsu API w jego imieniu. Aplikacja musi mieć tę zgodę, aby móc wykonać żądanie interfejsu Google API, które wymaga autoryzacji użytkownika.

Krok 1. Skonfiguruj obiekt kliencki

Jeśli do obsługi protokołu OAuth 2.0 używasz biblioteki klienta interfejsów API Google dla JavaScriptu, najpierw musisz skonfigurować obiekty gapi.auth2 i gapi.client. Te obiekty umożliwiają aplikacji uzyskiwanie autoryzacji użytkowników i wysyłanie autoryzowanych żądań do interfejsu API.

Obiekt klienta identyfikuje zakresy, do których aplikacja chce uzyskać dostęp. Wartości te określają ekran zgody, który Google wyświetla użytkownikowi.

Biblioteka klienta JS

Biblioteka klienta JavaScript upraszcza wiele aspektów procesu autoryzacji:

  1. Tworzy on przekierowanie na serwer autoryzacji Google i udostępnia metodę przekierowania użytkownika na ten adres.
  2. Obsługuje on przekierowanie z tego serwera z powrotem do Twojej aplikacji.
  3. Sprawdza on token dostępu zwrócony przez serwer autoryzacji.
  4. Zapisuje token dostępu wysyłany przez serwer autoryzacji do aplikacji i pobiera go, gdy aplikacja wywoła następnie autoryzowane wywołania interfejsu API.

Poniżej znajduje się fragment przykładowego przykładu pokazanego później w tym dokumencie. Ten kod inicjuje obiekt gapi.client, którego aplikacja będzie później używać do wywoływania interfejsu API. Po utworzeniu tego obiektu inicjowany jest też obiekt gapi.auth2, który jest używany przez aplikację do sprawdzania i monitorowania stanu autoryzacji użytkownika.

Wywołanie gapi.client.init określa te pola:

  • Wartości apiKey i clientId określają dane uwierzytelniające aplikacji. Zgodnie z sekcją Tworzenie danych uwierzytelniających te wartości można uzyskać w polu API Console. Uwaga: właściwość clientId jest wymagana, jeśli aplikacja wysyła autoryzowane żądania do interfejsu API. Aplikacje wysyłające tylko nieautoryzowane żądania mogą jedynie określić klucz interfejsu API.
  • Pole scope określa oddzieloną spacjami listę zakresów dostępu odpowiadających zasobom, do których aplikacja może uzyskiwać dostęp w imieniu użytkownika. Te wartości informują ekran zgody, który Google wyświetla użytkownikowi.

    Zalecamy, aby w miarę możliwości aplikacja prosiła o dostęp do zakresów autoryzacji. Prosząc o dostęp do danych użytkownika w kontekście, korzystając z autoryzacji przyrostowej, ułatwiasz użytkownikom zrozumienie, dlaczego Twoja aplikacja potrzebuje dostępu.

  • Pole discoveryDocs zawiera listę dokumentów Discovery Discovery używanych przez Twoją aplikację. Dokument Discovery opisuje interfejs API, w tym jego schematy zasobów, a biblioteka klienta JavaScript używa tych informacji do generowania metod, których aplikacje mogą używać. W tym przykładzie kod pobiera dokument wykrywania w wersji 3 interfejsu Google Drive API.

Po zakończeniu wywołania gapi.client.init kod ustawia zmienną GoogleAuth identyfikującą obiekt uwierzytelniania Google. Na koniec kod określa detektor, który wywołuje funkcję, gdy zmieni się stan logowania użytkownika. Ta funkcja nie jest zdefiniowana we fragmencie kodu.

var GoogleAuth; // Google Auth object.
function initClient() {
  gapi.client.init({
      'apiKey': 'YOUR_API_KEY',
      'clientId': 'YOUR_CLIENT_ID',
      'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
      'discoveryDocs': ['https://www.googleapis.com/discovery/v1/apis/drive/v3/rest']
  }).then(function () {
      GoogleAuth = gapi.auth2.getAuthInstance();

      // Listen for sign-in state changes.
      GoogleAuth.isSignedIn.listen(updateSigninStatus);
  });
}

Punkty końcowe OAuth 2.0

Jeśli masz bezpośredni dostęp do punktów końcowych OAuth 2.0, możesz przejść do następnego kroku.

Krok 2. Przekieruj na serwer OAuth 2.0 Google

Aby poprosić o dostęp do danych użytkownika, przekieruj go na serwer OAuth 2.0 Google.

Biblioteka klienta JS

Wywołaj metodę GoogleAuth.signIn(), aby przekierować użytkownika na serwer autoryzacji Google.

GoogleAuth.signIn();

W praktyce aplikacja może ustawić wartość logiczną określającą, czy wywołać metodę signIn() przed wywołaniem interfejsu API.

Fragment kodu poniżej pokazuje, jak rozpocząć procedurę autoryzacji użytkownika. Weź pod uwagę te informacje o krótkim opisie:

  • Obiekt GoogleAuth, do którego odwołuje się kod, jest taki sam jak zmienna globalna zdefiniowana we fragmencie kodu w kroku 1.

  • Funkcja updateSigninStatus to detektor, który wykrywa zmiany stanu autoryzacji użytkownika. Jej rola jako detektor została też określona we fragmencie kodu w kroku 1:
    GoogleAuth.isSignedIn.listen(updateSigninStatus);
    .
  • Fragment definiuje 2 dodatkowe zmienne globalne:

    • isAuthorized to zmienna logiczna, która wskazuje, czy użytkownik jest już zalogowany. Tę wartość można ustawić podczas wczytywania i aktualizowania aplikacji, gdy użytkownik się w niej zaloguje lub wyloguje.

      W tym fragmencie funkcji sendAuthorizedApiRequest sprawdza wartość zmiennej, aby określić, czy aplikacja powinna podjąć żądanie do interfejsu API, które wymaga autoryzacji, lub poprosić użytkownika o autoryzację.

    • currentApiRequest to obiekt, który zawiera szczegółowe informacje o ostatnim żądaniu interfejsu API podjętym przez użytkownika. Wartość obiektu jest ustawiana, gdy aplikacja wywołuje funkcję sendAuthorizedApiRequest.

      Jeśli użytkownik autoryzował aplikację, żądanie zostanie wykonane od razu. W przeciwnym razie funkcja przekierowuje użytkownika, aby się zalogować. Gdy użytkownik się zaloguje, funkcja updateSignInStatus wywołuje metodę sendAuthorizedApiRequest, przekazując to samo żądanie próby przed rozpoczęciem procesu autoryzacji.

var isAuthorized;
var currentApiRequest;

/**
 * Store the request details. Then check to determine whether the user
 * has authorized the application.
 *   - If the user has granted access, make the API request.
 *   - If the user has not granted access, initiate the sign-in flow.
 */
function sendAuthorizedApiRequest(requestDetails) {
  currentApiRequest = requestDetails;
  if (isAuthorized) {
    // Make API request
    // gapi.client.request(requestDetails)

    // Reset currentApiRequest variable.
    currentApiRequest = {};
  } else {
    GoogleAuth.signIn();
  }
}

/**
 * Listener called when user completes auth flow. If the currentApiRequest
 * variable is set, then the user was prompted to authorize the application
 * before the request executed. In that case, proceed with that API request.
 */
function updateSigninStatus(isSignedIn) {
  if (isSignedIn) {
    isAuthorized = true;
    if (currentApiRequest) {
      sendAuthorizedApiRequest(currentApiRequest);
    }
  } else {
    isAuthorized = false;
  }
}

Punkty końcowe OAuth 2.0

Wygeneruj URL, aby poprosić o dostęp z punktu końcowego OAuth 2.0 Google na adres https://accounts.google.com/o/oauth2/v2/auth. Ten punkt końcowy jest dostępny przez HTTPS. Odrzucane są zwykłe połączenia HTTP.

Serwer autoryzacji Google obsługuje te parametry ciągu zapytania w przypadku aplikacji internetowych:

Parametry
client_id Wymagany

Identyfikator klienta Twojej aplikacji. Ta wartość jest podana w API Console Credentials page.

redirect_uri Wymagany

Określa, gdzie serwer interfejsu API przekierowuje użytkownika po zakończeniu procesu autoryzacji. Wartość musi dokładnie odpowiadać jednemu z autoryzowanych identyfikatorów URI przekierowania dla klienta OAuth 2.0 skonfigurowanego przez Ciebie w API ConsoleCredentials page. Jeśli ta wartość nie pasuje do autoryzowanego identyfikatora URI przekierowania dla podanego atrybutu client_id, wystąpi błąd redirect_uri_mismatch.

Pamiętaj, że schemat http, https oraz ukośnik („/”) muszą być takie same.

response_type Wymagany

Aplikacje JavaScript muszą ustawić wartość parametru na token. Ta wartość instruuje serwer autoryzacji Google, aby zwracał token dostępu jako parę name=value w identyfikatorze fragmentu identyfikatora URI (#), do którego użytkownik jest przekierowywany po zakończeniu procesu autoryzacji.

scope Wymagany

Lista rozdzielonych spacjami zakresów określających zasoby, do których aplikacja może uzyskiwać dostęp w imieniu użytkownika. Te wartości określają ekran zgody, który Google wyświetla użytkownikowi.

Zakresy umożliwiają aplikacji żądanie tylko dostępu do potrzebnych zasobów, a jednocześnie umożliwienie użytkownikom kontrolowania poziomu dostępu przyznanego aplikacji. Dlatego występuje odwrotna zależność między liczbą żądanych zakresów a prawdopodobieństwem uzyskania zgody użytkownika.

Zalecamy, aby w miarę możliwości aplikacja prosiła o dostęp do zakresów autoryzacji. Prosząc o dostęp do danych użytkownika w kontekście, korzystając z autoryzacji przyrostowej, ułatwiasz użytkownikom zrozumienie, dlaczego Twoja aplikacja potrzebuje dostępu.

state Zalecane

Określa dowolną wartość ciągu tekstowego, której aplikacja używa do utrzymania stanu między żądaniem autoryzacji a odpowiedzią serwera autoryzacji. Gdy użytkownik wyrazi zgodę na dostęp do aplikacji, serwer zwróci dokładną wartość, którą wyślesz jako parę name=value w identyfikatorze fragmentu adresu URL (#) w redirect_uri.

Możesz używać tego parametru do różnych celów, takich jak kierowanie użytkownika do odpowiedniego zasobu w aplikacji, wysyłanie jednorazowych żądań lub łagodzenie sfałszowanych żądań z innych witryn. Odgadniesz wartość redirect_uri, więc użycie wartości state może zwiększyć pewność, że połączenie przychodzące jest wynikiem żądania uwierzytelniania. Jeśli generujesz losowy ciąg kodu lub kodujesz hasz pliku cookie albo inną wartość, która rejestruje 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 typu sfałszowanie żądania z innej witryny. Przykład tworzenia i potwierdzenia tokena state znajdziesz w dokumentacji OpenID Connect.

include_granted_scopes Opcjonalny

Umożliwia aplikacjom korzystanie z przyrostowej autoryzacji do żądania dostępu do dodatkowych zakresów w kontekście. Jeśli ustawisz wartość tego parametru na true, a prośba o autoryzację zostanie przyznana, nowy token dostępu będzie też obejmować wszystkie zakresy, do których użytkownik wcześniej przyznał dostęp aplikacji. Przykłady znajdziesz w sekcji Autoryzacja przyrostowa.

login_hint Opcjonalny

Jeśli aplikacja wie, który użytkownik próbuje się uwierzytelnić, może użyć tego parametru, aby podać serwerowi uwierzytelniania Google. Serwer wykorzystuje wskazówkę, aby uprościć proces logowania, wypełniając pole e-maila w formularzu logowania lub wybierając odpowiednią sesję wielokrotnego logowania.

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

prompt Opcjonalny

Lista rozdzielonych spacjami (z rozróżnianiem wielkości liter) próśb o podanie informacji użytkownikowi. Jeśli nie określisz tego parametru, użytkownik zostanie poproszony tylko o pierwsze żądanie dostępu. Więcej informacji znajdziesz w artykule Wysyłanie prośby o ponowną zgodę.

Możliwe wartości to:

none Nie wyświetlaj żadnych ekranów uwierzytelniania ani zgody. Nie można określać innych wartości.
consent Pytaj użytkownika o zgodę na wykorzystanie danych.
select_account Pytaj użytkownika o wybór konta.

Przykład przekierowania na serwer autoryzacji Google

Przykładowy URL jest wyświetlany poniżej, z podziałami wierszy i spacjami, aby można było go odczytać.

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly&
 include_granted_scopes=true&
 response_type=token&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

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

Przykładowy kod JavaScript

Poniższy fragment kodu JavaScript pokazuje, jak rozpocząć procedurę autoryzacji w JavaScript bez korzystania z biblioteki klienta interfejsów API Google dla JavaScriptu. Ten punkt końcowy OAuth 2.0 nie obsługuje udostępniania zasobów z różnych domen (CORS), dlatego fragment kodu tworzy formularz, który otwiera żądanie kierowane do tego punktu końcowego.

/*
 * Create form to request access token from Google's OAuth 2.0 server.
 */
function oauthSignIn() {
  // Google's OAuth 2.0 endpoint for requesting an access token
  var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';

  // Create <form> element to submit parameters to OAuth 2.0 endpoint.
  var form = document.createElement('form');
  form.setAttribute('method', 'GET'); // Send as a GET request.
  form.setAttribute('action', oauth2Endpoint);

  // Parameters to pass to OAuth 2.0 endpoint.
  var params = {'client_id': 'YOUR_CLIENT_ID',
                'redirect_uri': 'YOUR_REDIRECT_URI',
                'response_type': 'token',
                'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
                'include_granted_scopes': 'true',
                'state': 'pass-through value'};

  // Add form parameters as hidden input values.
  for (var p in params) {
    var input = document.createElement('input');
    input.setAttribute('type', 'hidden');
    input.setAttribute('name', p);
    input.setAttribute('value', params[p]);
    form.appendChild(input);
  }

  // Add form to page and submit it to open the OAuth 2.0 endpoint.
  document.body.appendChild(form);
  form.submit();
}

Krok 3. Google prosi użytkownika o zgodę

W tym kroku użytkownik decyduje, czy przyznać aplikacji żądany dostęp. Na tym etapie Google wyświetla okno zgody z nazwą aplikacji i usługami interfejsu API Google, których dotyczy prośba o przyznanie dostępu z użyciem danych uwierzytelniających użytkownika i podsumowaniem zakresów dostępu, które chcesz przyznać. Użytkownik może wyrazić zgodę na przyznanie dostępu do co najmniej 1 zakresu wymaganego przez aplikację lub odrzucić prośbę.

Twoja aplikacja nie musi nic robić na tym etapie, ponieważ czeka na odpowiedź serwera OAuth 2.0 Google i określa, czy przyznano dostęp. Odpowiedź została wyjaśniona w następnym kroku.

Błędy

Żądania wysyłane do punktów końcowych autoryzacji OAuth 2.0 Google mogą wyświetlać komunikaty o błędach wyświetlane użytkownikom, a nie oczekiwane przepływy 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 1 zakresu wymaganego przez zasady Google Workspace administratora. Zapoznaj się z artykułem pomocy dla administratorów Google Workspace, aby dowiedzieć się, które aplikacje innych firm i aplikacje wewnętrzne mają dostęp do danych Google Workspace. Dowiesz się z niego, jak administrator może ograniczyć dostęp do wszystkich zakresów lub poufnych i ograniczonych zakresów.

disallowed_useragent

Punkt końcowy autoryzacji jest wyświetlany w umieszczonym kliencie użytkownika niezgodnym z zasadami Google dotyczącymi protokołu OAuth 2.0.

Android

Deweloperzy Androida mogą zobaczyć ten komunikat o błędzie podczas otwierania żądań autoryzacji w android.webkit.WebView. Zamiast tego deweloperzy powinni korzystać z bibliotek Androida, takich jak Logowanie przez Google na Androida czy AppAuth na Androida stworzone przez OpenID Foundation.

Ten błąd może wystąpić, gdy aplikacja na Androida otwiera ogólny link internetowy w umieszczonym kliencie użytkownika, a użytkownik przechodzi do punktu końcowego autoryzacji OAuth 2.0 Twojej witryny. Deweloperzy powinni zezwolić na otwieranie ogólnych linków w domyślnym module obsługi linków systemu operacyjnego, który obejmuje zarówno moduły Linków aplikacji na Androida, jak i domyślną aplikację przeglądarki. Obsługiwaną jest też biblioteka Niestandardowe karty.

iOS

Programy na iOS i macOS mogą napotkać ten błąd podczas otwierania żądań autoryzacji w WKWebView. Zamiast tego deweloperzy powinni korzystać z bibliotek iOS, takich jak Logowanie przez Google na iOS czy AppAuth for iOS w Funding Choices.

Ten błąd może wystąpić, gdy aplikacja na iOS lub macOS otwiera ogólny link internetowy w umieszczonym kliencie użytkownika, a użytkownik przechodzi do punktu końcowego autoryzacji OAuth 2.0 Twojej witryny. Deweloperzy powinni zezwolić na otwieranie ogólnych linków w domyślnym module obsługi linków systemu operacyjnego, który zawiera zarówno moduły uniwersalnych linków, jak i domyślną aplikację przeglądarki. Biblioteka SFSafariViewController też jest obsługiwana.

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 User type (Typ użytkownika) w artykule „Konfigurowanie ekranu zgody OAuth” artykułu pomocy.

origin_mismatch

Schemat, domena lub port JavaScriptu, z którego pochodzi żądanie autoryzacji, mogą nie być zgodne z autoryzowanym identyfikatorem URI źródła JavaScript zarejestrowanym dla identyfikatora klienta OAuth. Sprawdź autoryzowane źródła JavaScript w Google API ConsoleCredentials page.

redirect_uri_mismatch

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

Schemat, domena lub port JavaScriptu, z którego pochodzi żądanie autoryzacji, mogą nie być zgodne z autoryzowanym identyfikatorem URI źródła JavaScript zarejestrowanym dla identyfikatora klienta OAuth. Sprawdź autoryzowane źródła JavaScript w sekcji Google API Console Credentials page.

Krok 4. Przetwórz odpowiedź serwera OAuth 2.0

Biblioteka klienta JS

Biblioteka klienta JavaScript obsługuje odpowiedź z serwera autoryzacji Google. Jeśli skonfigurujesz detektor do monitorowania zmian w stanie logowania bieżącego użytkownika, funkcja ta będzie wywoływana, gdy użytkownik przyzna żądany dostęp do aplikacji.

Punkty końcowe OAuth 2.0

Serwer OAuth 2.0 wysyła odpowiedź na żądanie redirect_uri określone w żądaniu tokena dostępu.

Jeśli użytkownik zatwierdzi prośbę, odpowiedź będzie zawierać token dostępu. Jeśli użytkownik nie zatwierdzi prośby, w odpowiedzi zostanie wyświetlony komunikat o błędzie. Token dostępu lub komunikat o błędzie jest zwracany we fragmencie skrótu identyfikatora URI przekierowania, jak w poniższym przykładzie:

  • Odpowiedź tokena dostępu:

    https://oauth2.example.com/callback#access_token=4/P7q7W91&token_type=Bearer&expires_in=3600

    Oprócz parametru access_token fragment ciągu zawiera też parametr token_type, który zawsze ma wartość Bearer, oraz parametr expires_in, który określa czas życia tokena w sekundach. Jeśli w żądaniu tokena dostępu określono parametr state, jego wartość jest uwzględniona w odpowiedzi.

  • Odpowiedź o błędzie:
    https://oauth2.example.com/callback#error=access_denied

Przykładowa odpowiedź serwera OAuth 2.0

Aby przetestować ten proces, kliknij ten przykładowy URL, który umożliwia dostęp tylko do odczytu do plików na Dysku Google:

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly&
 include_granted_scopes=true&
 response_type=token&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

Gdy zakończysz proces OAuth 2.0, przekierujemy Cię do aplikacji http://localhost/oauth2callback. Ten adres URL zwróci błąd 404 NOT FOUND, chyba że maszyna lokalna wyświetli plik pod tym adresem. Następny krok zawiera więcej informacji o tym, jakie informacje są podane w identyfikatorze URI, gdy użytkownik zostanie przekierowany z powrotem do aplikacji.

Wywołanie interfejsów API Google

Biblioteka klienta JS

Gdy aplikacja uzyska token dostępu, możesz używać biblioteki klienta JavaScript do wykonywania żądań API w imieniu użytkownika. Biblioteka klienta zarządza tokenem dostępu za Ciebie. Nie musisz robić nic specjalnego, aby wysłać go w żądaniu.

Biblioteka klienta obsługuje dwa sposoby wywoływania metod interfejsu API. Jeśli wczytano dokument wykrywania, interfejs API zdefiniuje funkcje za Ciebie. Możesz też użyć funkcji gapi.client.request, by wywołać metodę interfejsu API. Podane niżej 2 fragmenty pokazują te opcje dla metody interfejsu about.get Drive API.

// Example 1: Use method-specific function
var request = gapi.client.drive.about.get({'fields': 'user'});

// Execute the API request.
request.execute(function(response) {
  console.log(response);
});


// Example 2: Use gapi.client.request(args) function
var request = gapi.client.request({
  'method': 'GET',
  'path': '/drive/v3/about',
  'params': {'fields': 'user'}
});
// Execute the API request.
request.execute(function(response) {
  console.log(response);
});

Punkty końcowe OAuth 2.0

Gdy aplikacja otrzyma token dostępu, możesz go używać do wywoływania interfejsu API Google w imieniu danego konta użytkownika, jeśli zakresy dostępu wymagane przez ten interfejs API zostały przyznane. Aby to zrobić, dołącz do żądania do interfejsu API token dostępu, podając parametr zapytania access_token lub wartość nagłówka Authorization HTTP Bearer. W miarę możliwości preferowany jest nagłówek HTTP, ponieważ ciągi zapytania są zazwyczaj widoczne w dziennikach serwera. W większości przypadków biblioteki klienta możesz skonfigurować w wywołaniach interfejsów API Google (np. podczas wywoływania interfejsu Drive Files API).

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

Przykłady użycia HTTP GET

Wywołanie punktu końcowego drive.files (interfejs Drive Files API) z użyciem nagłówka HTTP Authorization: Bearer może wyglądać tak: 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 w przypadku 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

Te polecenia możesz 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

Przykładowy kod JavaScript

Fragment kodu poniżej pokazuje, jak użyć CORS (udostępniania zasobów między domenami), aby wysłać żądanie do interfejsu Google API. W tym przykładzie nie używamy biblioteki klienta interfejsów API Google dla JavaScriptu. Nawet jeśli nie korzystasz z biblioteki klienta, przewodnik pomocy CORS w jej dokumentacji prawdopodobnie pomoże Ci lepiej zrozumieć te żądania.

W tym fragmencie kodu zmienna access_token reprezentuje token uzyskany na potrzeby żądań interfejsu API w imieniu autoryzowanego użytkownika. Pełny przykład pokazuje, jak zapisać ten token w pamięci lokalnej przeglądarki i pobrać go podczas przesyłania żądania do interfejsu API.

var xhr = new XMLHttpRequest();
xhr.open('GET',
    'https://www.googleapis.com/drive/v3/about?fields=user&' +
    'access_token=' + params['access_token']);
xhr.onreadystatechange = function (e) {
  console.log(xhr.response);
};
xhr.send(null);

Pełny przykład

Biblioteka klienta JS

Przykładowy kod

Ta sekcja zawiera działającą wersję demonstracyjną przykładowego kodu, która pokazuje, jak kod działa w rzeczywistej aplikacji. Gdy autoryzujesz aplikację, pojawi się ona na liście aplikacji połączonych z Twoim kontem Google. Aplikacja nosi nazwę demonstracja OAuth 2.0 dla Dokumentów Google API. Podobnie, jeśli anulujesz dostęp i odświeżysz tę stronę, aplikacja nie będzie już wymieniona.

Pamiętaj, że ta aplikacja prosi o dostęp do zakresu https://www.googleapis.com/auth/drive.metadata.readonly. Dostęp jest wymagany tylko do zainicjowania przepływu OAuth 2.0 w aplikacji JavaScript. Aplikacja nie wysyła żadnych żądań do interfejsu API.

Przykładowy kod JavaScript

Jak pokazano powyżej, przykładowy kod dotyczy strony (aplikacji), która wczytuje bibliotekę klienta interfejsów API Google dla JavaScriptu i inicjuje przepływ OAuth 2.0. Strona zawiera:

  • Jeden przycisk, który umożliwia użytkownikowi zalogowanie się w aplikacji. Jeśli użytkownik wcześniej nie autoryzował aplikacji, uruchomi się proces OAuth 2.0.
  • Dwa przyciski, które pozwalają użytkownikowi wylogować się z aplikacji lub cofnąć dostęp przyznany wcześniej. W przypadku wylogowania się z aplikacji nie cofnięto jej przyznanego dostępu. Zanim aplikacja będzie mogła wysyłać inne autoryzowane żądania w Twoim imieniu, musisz przyznać dostęp ponownie. Gdy to zrobisz, musisz ponownie przyznać dostęp.

Dostęp do aplikacji możesz też anulować na stronie Uprawnienia na swoim koncie Google. Aplikacja jest oznaczona jako demonstracja OAuth 2.0 dla Dokumentów Google API.

<script>
  var GoogleAuth;
  var SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly';
  function handleClientLoad() {
    // Load the API's client and auth2 modules.
    // Call the initClient function after the modules load.
    gapi.load('client:auth2', initClient);
  }

  function initClient() {
    // In practice, your app can retrieve one or more discovery documents.
    var discoveryUrl = 'https://www.googleapis.com/discovery/v1/apis/drive/v3/rest';

    // Initialize the gapi.client object, which app uses to make API requests.
    // Get API key and client ID from API Console.
    // 'scope' field specifies space-delimited list of access scopes.
    gapi.client.init({
        'apiKey': 'YOUR_API_KEY',
        'clientId': 'YOUR_CLIENT_ID',
        'discoveryDocs': [discoveryUrl],
        'scope': SCOPE
    }).then(function () {
      GoogleAuth = gapi.auth2.getAuthInstance();

      // Listen for sign-in state changes.
      GoogleAuth.isSignedIn.listen(updateSigninStatus);

      // Handle initial sign-in state. (Determine if user is already signed in.)
      var user = GoogleAuth.currentUser.get();
      setSigninStatus();

      // Call handleAuthClick function when user clicks on
      //      "Sign In/Authorize" button.
      $('#sign-in-or-out-button').click(function() {
        handleAuthClick();
      });
      $('#revoke-access-button').click(function() {
        revokeAccess();
      });
    });
  }

  function handleAuthClick() {
    if (GoogleAuth.isSignedIn.get()) {
      // User is authorized and has clicked "Sign out" button.
      GoogleAuth.signOut();
    } else {
      // User is not signed in. Start Google auth flow.
      GoogleAuth.signIn();
    }
  }

  function revokeAccess() {
    GoogleAuth.disconnect();
  }

  function setSigninStatus() {
    var user = GoogleAuth.currentUser.get();
    var isAuthorized = user.hasGrantedScopes(SCOPE);
    if (isAuthorized) {
      $('#sign-in-or-out-button').html('Sign out');
      $('#revoke-access-button').css('display', 'inline-block');
      $('#auth-status').html('You are currently signed in and have granted ' +
          'access to this app.');
    } else {
      $('#sign-in-or-out-button').html('Sign In/Authorize');
      $('#revoke-access-button').css('display', 'none');
      $('#auth-status').html('You have not authorized this app or you are ' +
          'signed out.');
    }
  }

  function updateSigninStatus() {
    setSigninStatus();
  }
</script>

<button id="sign-in-or-out-button"
        style="margin-left: 25px">Sign In/Authorize</button>
<button id="revoke-access-button"
        style="display: none; margin-left: 25px">Revoke access</button>

<div id="auth-status" style="display: inline; padding-left: 25px"></div><hr>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script async defer src="https://apis.google.com/js/api.js"
        onload="this.onload=function(){};handleClientLoad()"
        onreadystatechange="if (this.readyState === 'complete') this.onload()">
</script>

Punkty końcowe OAuth 2.0

Ten przykładowy kod pokazuje, jak ukończyć proces OAuth 2.0 w JavaScript bez korzystania z biblioteki klienta interfejsów API Google dla JavaScriptu. Kod dotyczy strony HTML, która wyświetla przycisk umożliwiający wysłanie żądania do interfejsu API. Gdy go klikniesz, kod sprawdzi, czy strona zapisała token dostępu interfejsu API w pamięci lokalnej przeglądarki. Jeśli tak, wykonuje żądanie do interfejsu API. W przeciwnym razie inicjuje przepływ OAuth 2.0.

W przypadku protokołu OAuth 2.0 strona wygląda tak:

  1. Kieruje użytkownika do serwera OAuth 2.0 Google, który prosi o dostęp do zakresu https://www.googleapis.com/auth/drive.metadata.readonly.
  2. Gdy przyznasz (lub odrzucisz) dostęp do jednego lub większej liczby żądanych zakresów, użytkownik zostanie przekierowany na oryginalną stronę, która analizuje token dostępu z ciągu identyfikatora fragmentu.
  3. Strona używa tokena dostępu do wykonywania przykładowego żądania do interfejsu API.

    Żądanie interfejsu API wywołuje metodę about.get interfejsu API Dysku, aby uzyskać informacje o koncie Dysku Google autoryzowanego użytkownika.

  4. Jeśli żądanie zostanie wykonane, odpowiedź interfejsu API zostanie zarejestrowana w konsoli debugowania przeglądarki.

Dostęp do aplikacji możesz cofnąć na stronie Uprawnienia na swoim koncie Google. Aplikacja zostanie oznaczona jako demonstracja protokołu OAuth 2.0 w Dokumentach Google API.

Aby uruchomić ten kod lokalnie, musisz ustawić wartości zmiennych YOUR_CLIENT_ID i YOUR_REDIRECT_URI, które odpowiadają danych logowania. Zmienna YOUR_REDIRECT_URI powinna być ustawiona na ten sam adres URL, pod którym jest wyświetlana strona. Wartość musi dokładnie odpowiadać jednemu z autoryzowanych identyfikatorów URI przekierowania dla klienta OAuth 2.0 skonfigurowanego w API Console Credentials page. Jeśli ta wartość nie pasuje do autoryzowanego identyfikatora URI, wystąpi błąd redirect_uri_mismatch. Twój projekt musi też włączyć odpowiedni interfejs API dla tego żądania.

<html><head></head><body>
<script>
  var YOUR_CLIENT_ID = 'REPLACE_THIS_VALUE';
  var YOUR_REDIRECT_URI = 'REPLACE_THIS_VALUE';
  var fragmentString = location.hash.substring(1);

  // Parse query string to see if page request is coming from OAuth 2.0 server.
  var params = {};
  var regex = /([^&=]+)=([^&]*)/g, m;
  while (m = regex.exec(fragmentString)) {
    params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
  }
  if (Object.keys(params).length > 0) {
    localStorage.setItem('oauth2-test-params', JSON.stringify(params) );
    if (params['state'] && params['state'] == 'try_sample_request') {
      trySampleRequest();
    }
  }

  // If there's an access token, try an API request.
  // Otherwise, start OAuth 2.0 flow.
  function trySampleRequest() {
    var params = JSON.parse(localStorage.getItem('oauth2-test-params'));
    if (params && params['access_token']) {
      var xhr = new XMLHttpRequest();
      xhr.open('GET',
          'https://www.googleapis.com/drive/v3/about?fields=user&' +
          'access_token=' + params['access_token']);
      xhr.onreadystatechange = function (e) {
        if (xhr.readyState === 4 && xhr.status === 200) {
          console.log(xhr.response);
        } else if (xhr.readyState === 4 && xhr.status === 401) {
          // Token invalid, so prompt for user permission.
          oauth2SignIn();
        }
      };
      xhr.send(null);
    } else {
      oauth2SignIn();
    }
  }

  /*
   * Create form to request access token from Google's OAuth 2.0 server.
   */
  function oauth2SignIn() {
    // Google's OAuth 2.0 endpoint for requesting an access token
    var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';

    // Create element to open OAuth 2.0 endpoint in new window.
    var form = document.createElement('form');
    form.setAttribute('method', 'GET'); // Send as a GET request.
    form.setAttribute('action', oauth2Endpoint);

    // Parameters to pass to OAuth 2.0 endpoint.
    var params = {'client_id': YOUR_CLIENT_ID,
                  'redirect_uri': YOUR_REDIRECT_URI,
                  'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
                  'state': 'try_sample_request',
                  'include_granted_scopes': 'true',
                  'response_type': 'token'};

    // Add form parameters as hidden input values.
    for (var p in params) {
      var input = document.createElement('input');
      input.setAttribute('type', 'hidden');
      input.setAttribute('name', p);
      input.setAttribute('value', params[p]);
      form.appendChild(input);
    }

    // Add form to page and submit it to open the OAuth 2.0 endpoint.
    document.body.appendChild(form);
    form.submit();
  }
</script>

<button onclick="trySampleRequest();">Try sample request</button>
</body></html>

Reguły weryfikacji źródła JavaScript

Google stosuje poniższe reguły weryfikacji do źródeł JavaScript, aby pomagać deweloperom w ochronie aplikacji. Źródła JavaScript muszą być zgodne z tymi regułami. Definicję domeny, hosta i schematu znajdziesz poniżej w RFC 3986: sekcja 3.

Reguły weryfikacji
Schemat

Źródła JavaScript muszą używać schematu HTTPS, a nie zwykłego protokołu HTTP. Identyfikatory URI lokalnego hosta (w tym identyfikatory URI adresów IP lokalnych) są zwolnione z tej reguły.

Osoba prowadząca

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

Domena
  • Domeny najwyższego poziomu (domeny najwyższego poziomu) muszą należeć do listy domen publicznych.
  • Domeny hosta nie mogą być “googleusercontent.com”.
  • Źródła JavaScript nie mogą zawierać domen skracających adresy URL (np. goo.gl), chyba że aplikacja jest właścicielem domeny.
  • Informacje o użytkowniku

    Źródła JavaScript nie mogą zawierać podskładnika użytkownika.

    Ścieżka

    Źródła JavaScript nie mogą zawierać komponentu ścieżki.

    Zapytanie

    Źródła JavaScript nie mogą zawierać komponentu zapytania.

    Fragment

    Źródła JavaScript nie mogą zawierać komponentu fragmentu.

    Znaki Źródła JavaScript nie mogą zawierać niektórych znaków, w tym:
    • Symbole wieloznaczne ('*')
    • Znaki ASCII niedrukowalne
    • nieprawidłowe kodowanie procentowe (każdy procent kodowania niezgodny z kodem procentowym adresu URL po którym następuje 2 cyfry szesnastkowe)
    • Brak znaków (zakodowanego znaku NULL, np. %00, %C0%80)

    Autoryzacja przyrostowa

    W protokole OAuth 2.0 aplikacja prosi o autoryzację dostępu do zasobów zidentyfikowanych przez zakresy. Uznaje się, że najlepszym sposobem jest wysłanie prośby o autoryzację zasobów w odpowiednim momencie. Aby to zrobić, serwer autoryzacji Google obsługuje autoryzację przyrostową. Ta funkcja umożliwia żądanie zakresów, gdy jest to konieczne. Jeśli użytkownik przyzna uprawnienia dla nowego zakresu, zwróci kod autoryzacji, który można wymienić na token zawierający wszystkie zakresy przyznane przez użytkownika w projekcie.

    Na przykład aplikacja, która umożliwia użytkownikom próbkowanie utworów muzycznych i tworzenie miksów, może wymagać bardzo małej liczby zasobów. Zapisanie gotowej składanki wymaga jednak dostępu do Dysku Google. Większość osób uznałaby, że byłoby to naturalne w sytuacji, gdy prośba o dostęp do Dysku Google pojawiła się w chwili, gdy aplikacja jej potrzebowała.

    W takim przypadku aplikacja może poprosić o zakresy openid i profile, aby wykonać podstawowe logowanie, a następnie poprosić o zakres https://www.googleapis.com/auth/drive.file w chwili pierwszego żądania zapisania kombinacji.

    W przypadku tokena dostępu uzyskanego z przyrostowej autoryzacji obowiązują te reguły:

    • Tokenu można użyć do uzyskania dostępu do zasobów powiązanych z dowolnym z zakresów wdrożonych w nowej, połączonej autoryzacji.
    • Jeśli używasz tokenu odświeżania dla połączonej autoryzacji, aby uzyskać token dostępu, token dostępu reprezentuje połączoną autoryzację i może być używany dla dowolnej wartości scope w odpowiedzi.
    • Połączona autoryzacja obejmuje wszystkie zakresy przyznane przez użytkownika do projektu API, nawet jeśli prośba została przyznana przez różnych klientów. Jeśli na przykład użytkownik przyznał dostęp do jednego zakresu za pomocą klienta na komputery aplikacji, a potem kolejny zakres do tej samej aplikacji za pomocą klienta mobilnego, łączna autoryzacja będzie obejmować oba zakresy.
    • Jeśli unieważnisz token reprezentujący autoryzację autoryzacyjną, dostęp do wszystkich zakresów tej autoryzacji w imieniu powiązanego użytkownika zostanie unieważniony.

    Przykładowe fragmenty kodu pokazują, jak dodawać zakresy do istniejącego tokena dostępu. Dzięki temu Twoja aplikacja nie musi zarządzać wieloma tokenami dostępu.

    Biblioteka klienta JS

    Aby dodać zakresy do istniejącego tokena dostępu, wywołaj metodę GoogleUser.grant(options). Obiekt options wskazuje dodatkowe zakresy, do których chcesz przyznać dostęp.

    // Space-separated list of additional scope(s) you are requesting access to.
    // This code adds read-only access to the user's calendars via the Calendar API.
    var NEW_SCOPES = 'https://www.googleapis.com/auth/calendar.readonly';
    
    // Retrieve the GoogleUser object for the current user.
    var GoogleUser = GoogleAuth.currentUser.get();
    GoogleUser.grant({'scope': NEW_SCOPES});

    Punkty końcowe OAuth 2.0

    Aby dodać zakresy do istniejącego tokena dostępu, uwzględnij parametr include_granted_scopes w żądaniu do serwera OAuth 2.0 Google.

    Poniższy fragment kodu pokazuje, jak to zrobić. Fragment kodu zakładamy, że przechowujesz zakresy, dla których token dostępu jest prawidłowy w pamięci lokalnej przeglądarki. Kod (pełny przykład zawiera listę zakresów, dla których token dostępu jest prawidłowy, ustawiając właściwość oauth2-test-params.scope w pamięci lokalnej przeglądarki).

    Fragment kodu porównuje zakresy, dla których token dostępu jest prawidłowy, dla zakresu, którego chcesz użyć dla danego zapytania. Jeśli token dostępu nie obejmuje tego zakresu, rozpoczyna się proces OAuth 2.0. Funkcja oauth2SignIn jest zgodna z funkcją podaną w kroku 2 (i udostępnioną później w pełnym przykładzie).

    var SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly';
    var params = JSON.parse(localStorage.getItem('oauth2-test-params'));
    
    var current_scope_granted = false;
    if (params.hasOwnProperty('scope')) {
      var scopes = params['scope'].split(' ');
      for (var s = 0; s < scopes.length; s++) {
        if (SCOPE == scopes[s]) {
          current_scope_granted = true;
        }
      }
    }
    
    if (!current_scope_granted) {
      oauth2SignIn(); // This function is defined elsewhere in this document.
    } else {
      // Since you already have access, you can proceed with the API request.
    }

    Unieważnianie tokena

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

    Aplikacja może również automatycznie anulować przyznany jej dostęp. Automatyczne unieważnienie jest ważne wtedy, gdy użytkownik anuluje subskrypcję, usunie aplikację lub zmienią się zasoby interfejsu API wymagane przez aplikację. Innymi słowy, część procesu usuwania może obejmować żądanie do interfejsu API służące do zapewnienia, że uprawnienia przyznane aplikacji wcześniej zostaną usunięte.

    Biblioteka klienta JS

    Aby automatycznie unieważnić token, wywołaj GoogleAuth.disconnect():

    GoogleAuth.disconnect();

    Punkty końcowe OAuth 2.0

    Aby automatycznie unieważnić token, aplikacja wysyła żądanie do https://oauth2.googleapis.com/revoke i umieszcza go jako parametr:

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

    Może to być token dostępu lub token odświeżania. Jeśli token dostępu jest przypisany do odpowiedniego tokena odświeżania, zostanie on też unieważniony.

    Jeśli odwołanie zostanie przetworzone, kod stanu HTTP odpowiedzi będzie wyglądać tak: 200. W przypadku warunków błędu zwracany jest kod stanu HTTP 400 wraz z kodem błędu.

    Poniższy fragment kodu JavaScript pokazuje, jak unieważnić token w kodzie JavaScript bez korzystania z biblioteki klienta interfejsów API Google dla JavaScriptu. Unieważnianie tokenów OAuth 2.0 przez Google nie obsługuje udostępniania zasobów między domenami (CORS), więc kod tworzy formularz i przesyła go do punktu końcowego, zamiast publikować metodę za pomocą metody XMLHttpRequest().

    function revokeAccess(accessToken) {
      // Google's OAuth 2.0 endpoint for revoking access tokens.
      var revokeTokenEndpoint = 'https://oauth2.googleapis.com/revoke';
    
      // Create <form> element to use to POST data to the OAuth 2.0 endpoint.
      var form = document.createElement('form');
      form.setAttribute('method', 'post');
      form.setAttribute('action', revokeTokenEndpoint);
    
      // Add access token to the form so it is set as value of 'token' parameter.
      // This corresponds to the sample curl request, where the URL is:
      //      https://oauth2.googleapis.com/revoke?token={token}
      var tokenField = document.createElement('input');
      tokenField.setAttribute('type', 'hidden');
      tokenField.setAttribute('name', 'token');
      tokenField.setAttribute('value', accessToken);
      form.appendChild(tokenField);
    
      // Add form to page and submit it to actually revoke the token.
      document.body.appendChild(form);
      form.submit();
    }