Migracja do Google Identity Services

Omówienie

Aby uzyskać token dostępu dla poszczególnych użytkowników do wywoływania interfejsów API Google, Google udostępnia kilka bibliotek JavaScript:

W tym przewodniku znajdziesz instrukcje migracji z tych bibliotek do biblioteki Google Identity Services.

Dzięki temu przewodnikowi:

  • zastąp przestarzałą bibliotekę Platform Library biblioteką Identity Services.
  • Jeśli używasz biblioteki klienta interfejsu API, usuń przestarzały moduł gapi.auth2, jego metody i obiekty, zastępując je odpowiednikami z Identity Services.

Aby dowiedzieć się, co się zmieniło w bibliotece JavaScript Identity Services, przeczytaj omówieniejak działa autoryzacja użytkownika, aby zapoznać się z kluczowymi terminami i pojęciami.

Jeśli interesuje Cię uwierzytelnianie rejestracji użytkowników i logowania, zapoznaj się z artykułem Migracja z Logowania przez Google.

Identyfikowanie procesu autoryzacji

Istnieją 2 możliwe przepływy autoryzacji użytkownika: domyślny i autoryzacja za pomocą kodu.

Sprawdź swoją aplikację internetową, aby określić, jaki typ procesu autoryzacji jest obecnie używany.

Wskazania aplikacji internetowej korzystające z przepływu niejawnego:

Wskazuje, że aplikacja internetowa używa przepływu kodu autoryzacji:

W niektórych przypadkach kod źródłowy może obsługiwać oba procesy.

Wybieranie procesu autoryzacji

Zanim rozpoczniesz migrację, musisz ustalić, czy kontynuowanie dotychczasowego procesu czy zastosowanie innego procesu lepiej odpowiada Twoim potrzebom.

Aby poznać główne różnice i wady tych 2 procesów, przeczytaj artykuł Wybór procesu autoryzacji.

W większości przypadków zalecamy użycie przepływu kodu autoryzacji, ponieważ zapewnia on najwyższy poziom zabezpieczeń użytkownika. Wdrożenie tej procedury ułatwia też platformie dodawanie nowych funkcji offline, takich jak pobieranie aktualizacji, które powiadamiają użytkowników o ważnych zmianach w ich kalendarzu, zdjęciach, subskrypcjach itp.

Wybierz proces autoryzacji za pomocą selektorów poniżej.

Przepływ niejawny

Uzyskać token dostępu do korzystania z usługi w przeglądarce, gdy użytkownik jest obecny.

Przykłady strumienia domyślnego przedstawiają aplikacje internetowe przed i po migracji do usług tożsamości.

Przepływ kodu autoryzacji

Kod autoryzacji wydawany przez Google jest dostarczany do backendu Twojej platformy, gdzie jest wymieniany na token dostępu i token odświeżania.

Przykłady przepływu kodu autoryzacji przedstawiają aplikacje internetowe przed i po migracji do usług tożsamości.

W tym przewodniku postępuj zgodnie z instrukcjami wyróżnionymi czcionką pogrubioną, aby dodać, usunąć, zaktualizować lub zastąpić istniejące funkcje.

zmiany w aplikacji internetowej w przeglądarce;

W tej sekcji opisujemy zmiany, które wprowadzisz w aplikacji internetowej w przeglądarce podczas migracji do biblioteki JavaScript Google Identity Services.

Identyfikowanie kodu, którego dotyczy problem, i testowanie

Plik cookie debugowania pomaga znaleźć kod, którego dotyczy problem, i przetestować jego działanie po wycofaniu.

W przypadku dużych lub złożonych aplikacji znalezienie całego kodu, na który ma wpływ wycofanie modułu gapi.auth2, może być trudne. Aby prowadzić w konsoli rejestrowanie obecnie używanej funkcji, która wkrótce zostanie wycofana, ustaw wartość pliku cookie G_AUTH2_MIGRATION na informational. Opcjonalnie dodaj dwukropek, a po nim wartość klucza, która będzie też rejestrować miejsce na sesję. Po zalogowaniu się i uzyskaniu danych logowania sprawdź zebrane logi lub wyślij je do backendu w celu dalszej analizy. Na przykład funkcja informational:showauth2use zapisuje pochodzenie i adres URL w kluczu pamięci sesji o nazwie showauth2use.

Aby sprawdzić zachowanie aplikacji, gdy moduł gapi.auth2 nie jest już wczytywany, ustaw wartość pliku cookie G_AUTH2_MIGRATION na enforced. Umożliwia to przetestowanie zachowania po wycofaniu przed datą wprowadzenia.

Możliwe wartości plików cookie G_AUTH2_MIGRATION:

  • enforced Nie wczytuj modułu gapi.auth2.
  • informational Zaloguj w konsoli JS użycie wycofanej funkcji. Zapisuj też do pamięci sesji, gdy ustawiona jest opcjonalna nazwa klucza:informational:key-name.

Aby zminimalizować wpływ na użytkowników, zalecamy najpierw ustawienie tego pliku cookie lokalnie podczas tworzenia i testowania, a dopiero potem użycie go w środowiskach produkcyjnych.

Biblioteki i moduły

Moduł gapi.auth2 zarządza uwierzytelnianiem użytkownika w celu logowania się i domyślnym przepływem danych w celu autoryzacji. Zastąp ten wycofany moduł oraz jego obiekty i metody biblioteką Google Identity Services.

Dodaj bibliotekę usług tożsamości do aplikacji internetowej, dodając ją do dokumentu:

<script src="https://accounts.google.com/gsi/client" async defer></script>

Usuń wszystkie przypadki wczytywania modułu auth2 za pomocą gapi.load('auth2', function).

Biblioteka Google Identity Services zastępuje moduł gapi.auth2. Możesz nadal używać modułu gapi.client z biblioteki klienta interfejsu API Google dla JavaScriptu i korzystać z jego automatycznego tworzenia wywoływalnych metod JS z dokumentu wyszukiwania, grupowania wielu wywołań interfejsu API oraz funkcji zarządzania CORS.

Pliki cookie

Autoryzacja użytkownika nie wymaga użycia plików cookie.

Więcej informacji o tym, jak pliki cookie są używane do uwierzytelniania użytkowników, znajdziesz w artykule Przejście z funkcji logowania się w Google, a informacje o używaniu plików cookie przez inne usługi Google znajdziesz w artykule Jak Google używa plików cookie.

Dane logowania

Usługi tożsamości Google rozdzielają uwierzytelnianie i autoryzację na 2 różne operacje, a dane logowania użytkownika są oddzielne: token identyfikatora używany do identyfikowania użytkownika jest zwracany niezależnie od tokena dostępu używanego do autoryzacji.

Aby zobaczyć te zmiany, zapoznaj się z przykładowymi danymi logowania.

Przepływ niejawny

oddzielić uwierzytelnianie i autoryzację użytkownika, usuwając obsługę profilu użytkownika z przepływów autoryzacji;

Usuń te odwołania do klienta JavaScript Google Sign-In:

Metody

  • GoogleUser.getBasicProfile()
  • GoogleUser.getId()

Przepływ kodu autoryzacji

Usługi tożsamości dzielą dane logowania w przeglądarce na token tożsamości i token dostępu. Ta zmiana nie dotyczy danych uwierzytelniających uzyskanych przez bezpośrednie wywołania punktów końcowych Google OAuth 2.0 z platformy zaplecza ani przez biblioteki działające na bezpiecznym serwerze na platformie, np. klienta Google APIs Node.js.

Stan sesji

Wcześniej logowanie przez Google umożliwiało zarządzanie stanem zalogowania użytkownika za pomocą:

Odpowiadasz za zarządzanie stanem logowania i sesjami użytkowników w aplikacji internetowej.

Usuń te odwołania do klienta JavaScript logowania przez Google:

Obiekty:

  • gapi.auth2.SignInOptions

Metody:

  • GoogleAuth.attachClickHandler()
  • GoogleAuth.isSignedIn()
  • GoogleAuth.isSignedIn.get()
  • GoogleAuth.isSignedIn.listen()
  • GoogleAuth.signIn()
  • GoogleAuth.signOut()
  • GoogleAuth.currentUser.get()
  • GoogleAuth.currentUser.listen()
  • GoogleUser.isSignedIn()

Konfiguracja klienta

Zaktualizuj swoją aplikację internetową, aby zainicjować klienta tokena w ramach strumienia kodu autoryzacji lub strumienia domyślnego.

Usuń te odwołania do klienta JavaScript Google Sign-In:

Obiekty:

  • gapi.auth2.ClientConfig
  • gapi.auth2.OfflineAccessOptions

Metody:

  • gapi.auth2.getAuthInstance()
  • GoogleUser.grant()

Przepływ niejawny

Dodaj obiekt TokenClientConfig i wywołanie initTokenClient(), aby skonfigurować aplikację internetową, postępując zgodnie z przykładem inicjowania klienta tokena.

Zastąp odwołania do klienta Google Sign-In JavaScript usługami Google Identity Services:

Obiekty:

  • gapi.auth2.AuthorizeConfigTokenClientConfig

Metody:

  • gapi.auth2.init()google.accounts.oauth2.initTokenClient()

Parametry:

  • gapi.auth2.AuthorizeConfig.login_hint z TokenClientConfig.login_hint.
  • gapi.auth2.GoogleUser.getHostedDomain() z: TokenClientConfig.hd.

Przepływ kodu autoryzacji

Dodaj obiekt CodeClientConfig i wywołanie initCodeClient(), aby skonfigurować aplikację internetową, postępując zgodnie z przykładem inicjowania klienta kodu.

Gdy przechodzisz z przepływu niejawnego na przepływ kodu autoryzacji:

Usuń odniesienia do klienta JavaScript usługi logowania Google.

Obiekty:

  • gapi.auth2.AuthorizeConfig

Metody:

  • gapi.auth2.init()

Parametry:

  • gapi.auth2.AuthorizeConfig.login_hint
  • gapi.auth2.GoogleUser.getHostedDomain()

Żądanie tokena

Działanie użytkownika, np. kliknięcie przycisku, powoduje wysłanie żądania, które powoduje zwrócenie tokena dostępu bezpośrednio do przeglądarki użytkownika w ramach procesu domyślnego lub do platformy zaplecza po wymianie kodu autoryzacji na token dostępu i token odświeżania.

Przepływ niejawny

Tokeny dostępu można uzyskać i wykorzystywać w przeglądarce, gdy użytkownik jest zalogowany i ma aktywną sesję Google. W trybie domyślnym do wysłania żądania tokena dostępu wymagany jest gest użytkownika, nawet jeśli żądanie zostało już wysłane wcześniej.

Zastąp odwołania do klienta JavaScript logowania przez Google: Google Identity Services:

Metody:

  • gapi.auth2.authorize()TokenClient.requestAccessToken()
  • GoogleUser.reloadAuthResponse() z: TokenClient.requestAccessToken()

Dodaj link lub przycisk, aby wywołać funkcję requestAccessToken(), która inicjuje wyskakujące okienko z procesem UX służącym do żądania tokena dostępu lub do uzyskania nowego tokena po wygaśnięciu dotychczasowego.

Zaktualizuj bazę kodu, aby:

  • Uruchom przepływ tokenów OAuth 2.0 za pomocą requestAccessToken().
  • Obsługa stopniowej autoryzacji za pomocą requestAccessToken i OverridableTokenClientConfig w celu rozdzielenia jednego żądania dotyczącego wielu zakresów na kilka mniejszych żądań.
  • Poproś o nowy token, gdy obecny token wygaśnie lub zostanie unieważniony.

Praca z wieloma zakresami może wymagać wprowadzenia zmian strukturalnych w bazie kodu, aby można było poprosić o dostęp tylko do zakresów, które są potrzebne, a nie do wszystkich naraz. Jest to tzw. autoryzacja przyrostowa. Każde żądanie powinno zawierać jak najmniej zakresów, a najlepiej tylko jeden. Aby dowiedzieć się więcej o aktualizowaniu aplikacji w celu dodania autoryzacji stopniowej, zapoznaj się z artykułem Zarządzanie zgodą użytkownika.

Gdy token dostępu wygaśnie, moduł gapi.auth2 automatycznie pobiera nowy, ważny token dostępu do Twojej aplikacji internetowej. Aby zwiększyć bezpieczeństwo użytkowników, biblioteka Google Identity Services nie obsługuje automatycznego procesu odświeżania tokenów. Aby wykrywać wygasłe tokeny dostępu i prosić o nowe, musisz zaktualizować aplikację internetową. Więcej informacji znajdziesz w sekcji Obsługa tokenów.

Przepływ kodu autoryzacji

Dodaj link lub przycisk, aby wywołać funkcję requestCode() i poprosić Google o kod autoryzacji. Przykład znajdziesz w sekcji Wywoływanie procedury kodu OAuth 2.0.

Więcej informacji o tym, jak postępować w przypadku wygaśnięcia lub cofnięcia tokena dostępu, znajdziesz w sekcji „Obsługa tokenów” poniżej.

Obsługa tokenów

Dodaj obsługę błędów, aby wykrywać nieudane wywołania interfejsu API Google w przypadku użycia wygasłego lub unieważnionego tokena dostępu oraz zażądać nowego, prawidłowego tokena dostępu.

Gdy używany jest wygasły lub anulowany token dostępu, interfejsy API Google zwracają kod stanu HTTP 401 Unauthorized i komunikat o błędzie invalid_token. Przykład znajdziesz w artykule Odpowiedź dotycząca nieprawidłowego tokena.

Nieważne tokeny

Tokeny dostępu są krótkotrwałe i często ważne tylko przez kilka minut.

Unieważnienie tokena

Właściciel konta Google może w każdej chwili wycofać wcześniej wyrażoną zgodę. Spowoduje to unieważnienie istniejących tokenów dostępu i tokenów odświeżania. Odwołanie może zostać wywołane z Twojej platformy za pomocą revoke() lub za pomocą konta Google.

Zastąp odwołania do klienta JavaScript logowania przez Google: Google Identity Services:

Metody:

  • getAuthInstance().disconnect()google.accounts.oauth2.revoke()
  • GoogleUser.disconnect()google.accounts.oauth2.revoke()

Wywołaj funkcję revoke, gdy użytkownik usunie swoje konto na Twojej platformie lub wycofa zgodę na udostępnianie danych Twojej aplikacji.

Gdy Twoja aplikacja internetowa lub platforma backendowa poprosi o token dostępu, Google wyświetli użytkownikowi okno z prośbą o zgodę. Zobacz przykładowe okna z prośbą o zgodę na przetwarzanie danych wyświetlane użytkownikom przez Google.

Przed wydaniem tokena dostępu do aplikacji wymagana jest aktywna sesja Google, aby wyświetlić prośbę o zgodę użytkownika i zanotować wynik. Użytkownik może zostać poproszony o zalogowanie się na konto Google, jeśli nie została jeszcze utworzona bieżąca sesja.

Logowanie użytkownika

Użytkownicy mogą być zalogowani na konto Google na osobnej karcie przeglądarki lub bezpośrednio w przeglądarce lub systemie operacyjnym. Zalecamy dodanie do witryny opcji Zaloguj się przez Google, aby nawiązać aktywną sesję między kontem Google a przeglądarką, gdy użytkownik po raz pierwszy otworzy aplikację. Dzięki temu:

  • Zmniejsza liczbę logowań użytkownika. Żądanie tokena dostępu inicjuje proces logowania na konto Google, jeśli aktywna sesja nie istnieje.
  • Użyj bezpośrednio pola email danych logowania w tokenie tożsamości JWT jako wartości parametru login_hint w obiektach CodeClientConfig lub TokenClientConfig. Jest to szczególnie przydatne, jeśli Twoja platforma nie obsługuje systemu zarządzania kontami użytkowników.
  • wyszukiwać i powiązywać konto Google z dotychczasowym lokalnym kontem użytkownika na Twojej platformie, co pomaga ograniczyć liczbę duplikatów kont na platformie;
  • Podczas tworzenia nowego konta lokalnego można wyraźnie oddzielić okna dialogowe i procesy rejestracji od okien dialogowych i procesów uwierzytelniania użytkowników, co pozwoli zmniejszyć liczbę wymaganych czynności i zwiększyć współczynnik utrzymania.

Po zalogowaniu się, ale przed wydaniem tokena dostępu użytkownicy muszą wyrazić zgodę na żądane zakresy uprawnień aplikacji.

Po uzyskaniu zgody użytkownika zwracany jest token dostępu wraz z listą zakresów zatwierdzonych lub odrzuconych przez użytkownika.

Szczegółowe uprawnienia umożliwiają użytkownikom zatwierdzanie lub odrzucanie poszczególnych zakresów. Gdy żądasz dostępu do wielu zakresów, każdy z nich jest przyznawany lub odrzucany niezależnie od innych zakresów. W zależności od wyboru użytkownika aplikacja włącza funkcje zależne od konkretnego zakresu.

Przepływ niejawny

Zastąp odwołania do klienta Google Sign-In JavaScript usługami Google Identity Services:

Obiekty:

  • gapi.auth2.AuthorizeResponseTokenClient.TokenResponse
  • gapi.auth2.AuthResponseTokenClient.TokenResponse

Metody:

  • GoogleUser.hasGrantedScopes() z: google.accounts.oauth2.hasGrantedAllScopes()
  • GoogleUser.getGrantedScopes() z: google.accounts.oauth2.hasGrantedAllScopes()

Usuń odwołania do klienta JavaScript logowania przez Google:

Metody:

  • GoogleUser.getAuthResponse()

Zaktualizuj swoją aplikację internetową, korzystając z uprawnień hasGrantedAllScopes()hasGrantedAnyScope(). Aby to zrobić, postępuj zgodnie z tym przykładem dotyczącym szczegółowych uprawnień.

Przepływ kodu autoryzacji

Zaktualizuj lub dodaj punkt końcowy kodu autoryzacji na platformie backendowej, wykonując instrukcje podane w sekcji dotyczącej obsługi kodu autoryzacji.

Zaktualizuj swoją platformę, aby wykonać czynności opisane w instrukcji Używanie modelu CodeModel, które pozwolą zweryfikować żądanie i uzyskać token dostępu oraz token odświeżania.

Zaktualizuj swoją platformę, aby selektywnie włączać i wyłączać funkcje na podstawie poszczególnych zakresów zatwierdzonych przez użytkownika. Aby to zrobić, postępuj zgodnie z instrukcjami dotyczącymi autoryzacji stopniowejsprawdź zakresy dostępu przyznane przez użytkownika.

Przykłady przepływu niejawnego

Stara metoda

Biblioteka klienta GAPI

Przykład biblioteki klienta interfejsu Google API dla JavaScriptu działającej w przeglądarce i wyświetlającej okno dialogowe z prośbą o zgodę użytkownika.

Moduł gapi.auth2 jest automatycznie wczytywany i używany przez moduł gapi.client.init(), dlatego jest ukryty.

<!DOCTYPE html>
  <html>
    <head>
      <script src="https://apis.google.com/js/api.js"></script>
      <script>
        function start() {
          gapi.client.init({
            'apiKey': 'YOUR_API_KEY',
            'clientId': 'YOUR_CLIENT_ID',
            'scope': 'https://www.googleapis.com/auth/cloud-translation',
            'discoveryDocs': ['https://www.googleapis.com/discovery/v1/apis/translate/v2/rest'],
          }).then(function() {
            // Execute an API request which is returned as a Promise.
            // The method name language.translations.list comes from the API discovery.
            return gapi.client.language.translations.list({
              q: 'hello world',
              source: 'en',
              target: 'de',
            });
          }).then(function(response) {
            console.log(response.result.data.translations[0].translatedText);
          }, function(reason) {
            console.log('Error: ' + reason.result.error.message);
          });
        };

        // Load the JavaScript client library and invoke start afterwards.
        gapi.load('client', start);
      </script>
    </head>
    <body>
      <div id="results"></div>
    </body>
  </html>

Biblioteka klienta JS

OAuth 2.0 dla aplikacji internetowych po stronie klienta uruchomionych w przeglądarce z wyskakującym okienkiem wyrażania zgody przez użytkownika.

Moduł gapi.auth2 jest wczytywany ręcznie.

<!DOCTYPE html>
<html><head></head><body>
<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>
</body></html>

Punkty końcowe OAuth 2.0

OAuth 2.0 dla aplikacji internetowych po stronie klienta uruchomionych w przeglądarce i przekierowania do Google w celu uzyskania zgody użytkownika.

Ten przykład pokazuje bezpośrednie wywołania punktów końcowych OAuth 2.0 Google z przeglądarki użytkownika bez użycia modułu gapi.auth2 ani biblioteki JavaScript.

<!DOCTYPE html>
<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>

Nowa droga

Tylko GIS

Ten przykład pokazuje tylko bibliotekę JavaScript Google Identity Service korzystającą z modelu tokenów i okno z prośbą o zgodę użytkownika. Przykład ten ma na celu zilustrowanie minimalnej liczby kroków wymaganych do skonfigurowania klienta, zażądania i uzyskania tokena dostępu oraz wywołania interfejsu Google API.

<!DOCTYPE html>
<html>
  <head>
    <script src="https://accounts.google.com/gsi/client" onload="initClient()" async defer></script>
  </head>
  <body>
    <script>
      var client;
      var access_token;

      function initClient() {
        client = google.accounts.oauth2.initTokenClient({
          client_id: 'YOUR_CLIENT_ID',
          scope: 'https://www.googleapis.com/auth/calendar.readonly \
                  https://www.googleapis.com/auth/contacts.readonly',
          callback: (tokenResponse) => {
            access_token = tokenResponse.access_token;
          },
        });
      }
      function getToken() {
        client.requestAccessToken();
      }
      function revokeToken() {
        google.accounts.oauth2.revoke(access_token, () => {console.log('access token revoked')});
      }
      function loadCalendar() {
        var xhr = new XMLHttpRequest();
        xhr.open('GET', 'https://www.googleapis.com/calendar/v3/calendars/primary/events');
        xhr.setRequestHeader('Authorization', 'Bearer ' + access_token);
        xhr.send();
      }
    </script>
    <h1>Google Identity Services Authorization Token model</h1>
    <button onclick="getToken();">Get access token</button><br><br>
    <button onclick="loadCalendar();">Load Calendar</button><br><br>
    <button onclick="revokeToken();">Revoke token</button>
  </body>
</html>

GAPI async/await

Ten przykład pokazuje, jak dodać bibliotekę usługi Google Identity za pomocą modelu tokena, usunąć moduł gapi.auth2 i wywołać interfejs API za pomocą biblioteki klienta interfejsu API Google do obsługi JavaScriptu.

Obietnice, asynchroniczne i await służą do wymuszania kolejności wczytywania bibliotek oraz do przechwytywania i ponownie próbowania błędów autoryzacji. Wywołanie interfejsu API jest wykonywane dopiero po uzyskaniu prawidłowego tokena dostępu.

Użytkownicy powinni nacisnąć przycisk „Pokaż kalendarz”, gdy podczas pierwszego wczytywania strony brakuje tokena dostępu lub gdy jego ważność wygasa.

<!DOCTYPE html>
<html>
<head></head>
<body>
  <h1>GAPI with GIS async/await</h1>
  <button id="showEventsBtn" onclick="showEvents();">Show Calendar</button><br><br>
  <button id="revokeBtn" onclick="revokeToken();">Revoke access token</button>

  <script>

    const gapiLoadPromise = new Promise((resolve, reject) => {
      gapiLoadOkay = resolve;
      gapiLoadFail = reject;
    });
    const gisLoadPromise = new Promise((resolve, reject) => {
      gisLoadOkay = resolve;
      gisLoadFail = reject;
    });

    var tokenClient;

    (async () => {
      document.getElementById("showEventsBtn").style.visibility="hidden";
      document.getElementById("revokeBtn").style.visibility="hidden";

      // First, load and initialize the gapi.client
      await gapiLoadPromise;
      await new Promise((resolve, reject) => {
        // NOTE: the 'auth2' module is no longer loaded.
        gapi.load('client', {callback: resolve, onerror: reject});
      });
      await gapi.client.init({
        // NOTE: OAuth2 'scope' and 'client_id' parameters have moved to initTokenClient().
      })
      .then(function() {  // Load the Calendar API discovery document.
        gapi.client.load('https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest');
      });

      // Now load the GIS client
      await gisLoadPromise;
      await new Promise((resolve, reject) => {
        try {
          tokenClient = google.accounts.oauth2.initTokenClient({
              client_id: 'YOUR_CLIENT_ID',
              scope: 'https://www.googleapis.com/auth/calendar.readonly',
              prompt: 'consent',
              callback: '',  // defined at request time in await/promise scope.
          });
          resolve();
        } catch (err) {
          reject(err);
        }
      });

      document.getElementById("showEventsBtn").style.visibility="visible";
      document.getElementById("revokeBtn").style.visibility="visible";
    })();

    async function getToken(err) {

      if (err.result.error.code == 401 || (err.result.error.code == 403) &&
          (err.result.error.status == "PERMISSION_DENIED")) {

        // The access token is missing, invalid, or expired, prompt for user consent to obtain one.
        await new Promise((resolve, reject) => {
          try {
            // Settle this promise in the response callback for requestAccessToken()
            tokenClient.callback = (resp) => {
              if (resp.error !== undefined) {
                reject(resp);
              }
              // GIS has automatically updated gapi.client with the newly issued access token.
              console.log('gapi.client access token: ' + JSON.stringify(gapi.client.getToken()));
              resolve(resp);
            };
            tokenClient.requestAccessToken();
          } catch (err) {
            console.log(err)
          }
        });
      } else {
        // Errors unrelated to authorization: server errors, exceeding quota, bad requests, and so on.
        throw new Error(err);
      }
    }

    function showEvents() {

      // Try to fetch a list of Calendar events. If a valid access token is needed,
      // prompt to obtain one and then retry the original request.
      gapi.client.calendar.events.list({ 'calendarId': 'primary' })
      .then(calendarAPIResponse => console.log(JSON.stringify(calendarAPIResponse)))
      .catch(err  => getToken(err))  // for authorization errors obtain an access token
      .then(retry => gapi.client.calendar.events.list({ 'calendarId': 'primary' }))
      .then(calendarAPIResponse => console.log(JSON.stringify(calendarAPIResponse)))
      .catch(err  => console.log(err)); // cancelled by user, timeout, etc.
    }

    function revokeToken() {
      let cred = gapi.client.getToken();
      if (cred !== null) {
        google.accounts.oauth2.revoke(cred.access_token, () => {console.log('Revoked: ' + cred.access_token)});
        gapi.client.setToken('');
      }
    }

  </script>

  <script async defer src="https://apis.google.com/js/api.js" onload="gapiLoadOkay()" onerror="gapiLoadFail(event)"></script>
  <script async defer src="https://accounts.google.com/gsi/client" onload="gisLoadOkay()" onerror="gisLoadFail(event)"></script>

</body>
</html>

Wywołanie zwrotne GAPI

Ten przykład pokazuje, jak dodać bibliotekę Google Identity Service za pomocą modelu tokenów, usunąć moduł gapi.auth2 i wywołać interfejs API za pomocą biblioteki klienta interfejsu Google API dla JavaScript.

Zmienne służą do wymuszania kolejności wczytywania bibliotek. Wywołania GAPI są wykonywane z poziomu wywołania zwrotnego po zwróceniu prawidłowego tokena dostępu.

Użytkownicy powinni nacisnąć przycisk Pokaż kalendarz po pierwszym załadowaniu strony i ponownie, gdy chcą odświeżyć informacje z kalendarza.

<!DOCTYPE html>
<html>
<head>
  <script async defer src="https://apis.google.com/js/api.js" onload="gapiLoad()"></script>
  <script async defer src="https://accounts.google.com/gsi/client" onload="gisInit()"></script>
</head>
<body>
  <h1>GAPI with GIS callbacks</h1>
  <button id="showEventsBtn" onclick="showEvents();">Show Calendar</button><br><br>
  <button id="revokeBtn" onclick="revokeToken();">Revoke access token</button>
  <script>
    let tokenClient;
    let gapiInited;
    let gisInited;

    document.getElementById("showEventsBtn").style.visibility="hidden";
    document.getElementById("revokeBtn").style.visibility="hidden";

    function checkBeforeStart() {
       if (gapiInited && gisInited){
          // Start only when both gapi and gis are initialized.
          document.getElementById("showEventsBtn").style.visibility="visible";
          document.getElementById("revokeBtn").style.visibility="visible";
       }
    }

    function gapiInit() {
      gapi.client.init({
        // NOTE: OAuth2 'scope' and 'client_id' parameters have moved to initTokenClient().
      })
      .then(function() {  // Load the Calendar API discovery document.
        gapi.client.load('https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest');
        gapiInited = true;
        checkBeforeStart();
      });
    }

    function gapiLoad() {
        gapi.load('client', gapiInit)
    }

    function gisInit() {
     tokenClient = google.accounts.oauth2.initTokenClient({
                client_id: 'YOUR_CLIENT_ID',
                scope: 'https://www.googleapis.com/auth/calendar.readonly',
                callback: '',  // defined at request time
            });
      gisInited = true;
      checkBeforeStart();
    }

    function showEvents() {

      tokenClient.callback = (resp) => {
        if (resp.error !== undefined) {
          throw(resp);
        }
        // GIS has automatically updated gapi.client with the newly issued access token.
        console.log('gapi.client access token: ' + JSON.stringify(gapi.client.getToken()));

        gapi.client.calendar.events.list({ 'calendarId': 'primary' })
        .then(calendarAPIResponse => console.log(JSON.stringify(calendarAPIResponse)))
        .catch(err => console.log(err));

        document.getElementById("showEventsBtn").innerText = "Refresh Calendar";
      }

      // Conditionally ask users to select the Google Account they'd like to use,
      // and explicitly obtain their consent to fetch their Calendar.
      // NOTE: To request an access token a user gesture is necessary.
      if (gapi.client.getToken() === null) {
        // Prompt the user to select a Google Account and asked for consent to share their data
        // when establishing a new session.
        tokenClient.requestAccessToken({prompt: 'consent'});
      } else {
        // Skip display of account chooser and consent dialog for an existing session.
        tokenClient.requestAccessToken({prompt: ''});
      }
    }

    function revokeToken() {
      let cred = gapi.client.getToken();
      if (cred !== null) {
        google.accounts.oauth2.revoke(cred.access_token, () => {console.log('Revoked: ' + cred.access_token)});
        gapi.client.setToken('');
        document.getElementById("showEventsBtn").innerText = "Show Calendar";
      }
    }
  </script>
</body>
</html>

Przykłady przepływu kodu autoryzacji

Interfejs użytkownika wyskakującego okienka biblioteki Google Identity Service może używać przekierowania URL, aby zwrócić kod autoryzacji bezpośrednio do punktu końcowego tokena w systemie zaplecza, lub wywołania zwrotnego JavaScriptu działającego w przeglądarce użytkownika, który pośredniczy w przekazaniu odpowiedzi do Twojej platformy. W obu przypadkach platforma backendu wykona proces OAuth 2.0, aby uzyskać prawidłowy token odświeżania i token dostępu.

Stary sposób

Aplikacje internetowe po stronie serwera

Logowanie w Google w przypadku aplikacji działających po stronie serwera na platformie backendowej, które korzystają z przekierowania do Google w celu uzyskania zgody użytkownika.

<!DOCTYPE html>
<html>
  <head>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
    <script src="https://apis.google.com/js/client:platform.js?onload=start" async defer></script>
    <script>
      function start() {
        gapi.load('auth2', function() {
          auth2 = gapi.auth2.init({
            client_id: 'YOUR_CLIENT_ID',
            api_key: 'YOUR_API_KEY',
            discovery_docs: ['https://www.googleapis.com/discovery/v1/apis/translate/v2/rest'],
            // Scopes to request in addition to 'profile' and 'email'
            scope: 'https://www.googleapis.com/auth/cloud-translation',
          });
        });
      }
      function signInCallback(authResult) {
        if (authResult['code']) {
          console.log("sending AJAX request");
          // Send authorization code obtained from Google to backend platform
          $.ajax({
            type: 'POST',
            url: 'YOUR_AUTHORIZATION_CODE_ENDPOINT_URL',
            // Always include an X-Requested-With header to protect against CSRF attacks.
            headers: {
              'X-Requested-With': 'XMLHttpRequest'
            },
            contentType: 'application/octet-stream; charset=utf-8',
            success: function(result) {
              console.log(result);
            },
            processData: false,
            data: authResult['code']
          });
        } else {
          console.log('error: failed to obtain authorization code')
        }
      }
    </script>
  </head>
  <body>
    <button id="signinButton">Sign In With Google</button>
    <script>
      $('#signinButton').click(function() {
        // Obtain an authorization code from Google
        auth2.grantOfflineAccess().then(signInCallback);
      });
    </script>
  </body>
</html>

HTTP/REST przy użyciu przekierowania

Używanie OAuth 2.0 na potrzeby aplikacji serwera WWW do wysyłania kodu autoryzacji z przeglądarki użytkownika na platformę backendu. Zgoda użytkownika jest obsługiwana przez przekierowanie jego przeglądarki do Google.

/\*
 \* 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 &lt;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_AUTHORIZATION_CODE_ENDPOINT_URL',
                '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();
}

Nowy sposób

GIS Popup UX

Ten przykład pokazuje tylko bibliotekę JavaScript usługi Google Identity Service używającą modelu kodu autoryzacji, w którym wyświetla się wyskakujące okienko z prośbą o zgodę na przetwarzanie danych osobowych oraz moduł obsługi wywołania zwrotnego do otrzymania kodu autoryzacji od Google. Przykład ten ma na celu pokazanie minimalnej liczby kroków wymaganych do skonfigurowania klienta, uzyskania zgody i wysłania kodu autoryzacji do platformy zaplecza.

<!DOCTYPE html>
<html>
  <head>
    <script src="https://accounts.google.com/gsi/client" onload="initClient()" async defer></script>
  </head>
  <body>
    <script>
      var client;
      function initClient() {
        client = google.accounts.oauth2.initCodeClient({
          client_id: 'YOUR_CLIENT_ID',
          scope: 'https://www.googleapis.com/auth/calendar.readonly',
          ux_mode: 'popup',
          callback: (response) => {
            var code_receiver_uri = 'YOUR_AUTHORIZATION_CODE_ENDPOINT_URI',
            // Send auth code to your backend platform
            const xhr = new XMLHttpRequest();
            xhr.open('POST', code_receiver_uri, true);
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
            xhr.onload = function() {
              console.log('Signed in as: ' + xhr.responseText);
            };
            xhr.send('code=' + response.code);
            // After receipt, the code is exchanged for an access token and
            // refresh token, and the platform then updates this web app
            // running in user's browser with the requested calendar info.
          },
        });
      }
      function getAuthCode() {
        // Request authorization code and obtain user consent
        client.requestCode();
      }
    </script>
    <button onclick="getAuthCode();">Load Your Calendar</button>
  </body>
</html>

GIS Redirect UX

Model kodu autoryzacji obsługuje tryby interfejsu użytkownika dotyczące wysyłania wyskakującego okienka i przekierowania, aby przesłać kod autoryzacji dla poszczególnych użytkowników do punktu końcowego hostowanego przez Twoją platformę. Tryb przekierowania UX:

<!DOCTYPE html>
<html>
  <head>
    <script src="https://accounts.google.com/gsi/client" onload="initClient()" async defer></script>
  </head>
  <body>
    <script>
      var client;
      function initClient() {
        client = google.accounts.oauth2.initCodeClient({
          client_id: 'YOUR_CLIENT_ID',
          scope: 'https://www.googleapis.com/auth/calendar.readonly \
                  https://www.googleapis.com/auth/photoslibrary.readonly',
          ux_mode: 'redirect',
          redirect_uri: 'YOUR_AUTHORIZATION_CODE_ENDPOINT_URI'
        });
      }
      // Request an access token
      function getAuthCode() {
        // Request authorization code and obtain user consent
        client.requestCode();
      }
    </script>
    <button onclick="getAuthCode();">Load Your Calendar</button>
  </body>
</html>

Biblioteki JavaScript

Usługi tożsamości Google to pojedyncza biblioteka JavaScript używana do uwierzytelniania i autoryzacji użytkowników. Łączy ona i zastępuje funkcje występujące w wielu różnych bibliotekach i modułach:

Działania, które należy wykonać podczas migracji do usług tożsamości:

Istniejąca biblioteka JS Nowa biblioteka JS Uwagi
apis.google.com/js/api.js accounts.google.com/gsi/client Dodaj nową bibliotekę i postępuj zgodnie z domyślnym procesem.
apis.google.com/js/client.js accounts.google.com/gsi/client Dodaliśmy nową bibliotekę i przepływ danych dotyczący kodu autoryzacji.

Krótkie omówienie biblioteki

Porównanie obiektów i metod między starą biblioteką klienta JavaScript sterowania uwierzytelnianiem Googlenową biblioteką Google Identity Services oraz uwagi z dodatkowymi informacjami i działaniami do wykonania podczas migracji.

Stary Nowe Uwagi
Obiekt GoogleAuth i powiązane metody:
GoogleAuth.attachClickHandler() Usuń
GoogleAuth.currentUser.get() Usuń
GoogleAuth.currentUser.listen() Usuń
GoogleAuth.disconnect() google.accounts.oauth2.revoke Zastąp stare nowymi. Odwołanie zgody może nastąpić również na stronie https://myaccount.google.com/permissions.
GoogleAuth.grantOfflineAccess() Usuń, postępując zgodnie z przepływem kodu autoryzacji.
GoogleAuth.isSignedIn.get() Usuń
GoogleAuth.isSignedIn.listen() Usuń
GoogleAuth.signIn() Usuń
GoogleAuth.signOut() Usuń
GoogleAuth.then() Usuń
Obiekt GoogleUser i powiązane metody:
GoogleUser.disconnect() google.accounts.id.revoke Zamień stare na nowe. Odwołanie zgody może nastąpić również na stronie https://myaccount.google.com/permissions.
GoogleUser.getAuthResponse() requestCode() or requestAccessToken() Zastąp stare nowymi
GoogleUser.getBasicProfile() Usuń. Zamiast tego użyj tokena identyfikacyjnego. Więcej informacji znajdziesz w artykule Przejście z funkcji logowania Google.
GoogleUser.getGrantedScopes() hasGrantedAnyScope() Zastąp stare nowymi
GoogleUser.getHostedDomain() Usuń
GoogleUser.getId() Usuń
GoogleUser.grantOfflineAccess() Usuń, postępując zgodnie z przepływem kodu autoryzacji.
GoogleUser.grant() Usuń
GoogleUser.hasGrantedScopes() hasGrantedAnyScope() Zastąp stare nowymi
GoogleUser.isSignedIn() Usuń
GoogleUser.reloadAuthResponse() requestAccessToken() Usuń stary, wywołaj nowy, aby zastąpić wygasły lub unieważniony token dostępu.
Obiekt gapi.auth2 i powiązane metody:
Obiekt gapi.auth2.AuthorizeConfig TokenClientConfig lub CodeClientConfig Zastąp stare nowymi
Obiekt „gapi.auth2.AuthorizeResponse” Usuń
Obiekt gapi.auth2.AuthResponse Usuń
gapi.auth2.authorize() requestCode() or requestAccessToken() Zastąp stare nowymi
gapi.auth2.ClientConfig() TokenClientConfig lub CodeClientConfig Zamień stare na nowe
gapi.auth2.getAuthInstance() Usuń
gapi.auth2.init() initTokenClient() or initCodeClient() Zastąp stare nowymi
Obiekt gapi.auth2.OfflineAccessOptions Usuń
Obiekt gapi.auth2.SignInOptions Usuń
Obiekt gapi.signin2 i powiązane metody:
gapi.signin2.render() Usuń. Wczytanie DOM HTML elementu g_id_signin lub wywołanie JS do google.accounts.id.renderButton powoduje zalogowanie użytkownika na konto Google.

Przykładowe dane logowania

Istniejące dane logowania

Biblioteka platformy Logowanie przez Google, biblioteka klienta interfejsu API Google dla JavaScriptu lub bezpośrednie wywołania punktów końcowych Google Auth 2.0 zwracają w jednym odpowiedzi zarówno token dostępu OAuth 2.0, jak i token identyfikatora OpenID Connect.

Przykładowa odpowiedź zawierająca zarówno access_token, jak i id_token:

  {
    "token_type": "Bearer",
    "access_token": "ya29.A0ARrdaM-SmArZaCIh68qXsZSzyeU-8mxhQERHrP2EXtxpUuZ-3oW8IW7a6D2J6lRnZrRj8S6-ZcIl5XVEqnqxq5fuMeDDH_6MZgQ5dgP7moY-yTiKR5kdPm-LkuPM-mOtUsylWPd1wpRmvw_AGOZ1UUCa6UD5Hg",
    "scope": "https://www.googleapis.com/auth/calendar.readonly",
    "login_hint": "AJDLj6I2d1RH77cgpe__DdEree1zxHjZJr4Q7yOisoumTZUmo5W2ZmVFHyAomUYzLkrluG-hqt4RnNxrPhArd5y6p8kzO0t8xIfMAe6yhztt6v2E-_Bb4Ec3GLFKikHSXNh5bI-gPrsI",
    "expires_in": 3599,
    "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjkzNDFhYmM0MDkyYjZmYzAzOGU0MDNjOTEwMjJkZDNlNDQ1MzliNTYiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwiYXpwIjoiNTM4MzQ0NjUzMjU1LTc1OGM1aDVpc2M0NXZnazI3ZDhoOGRlYWJvdnBnNnRvLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiYXVkIjoiNTM4MzQ0NjUzMjU1LTc1OGM1aDVpc2M0NXZnazI3ZDhoOGRlYWJvdnBnNnRvLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwic3ViIjoiMTE3NzI2NDMxNjUxOTQzNjk4NjAwIiwiaGQiOiJnb29nbGUuY29tIiwiZW1haWwiOiJkYWJyaWFuQGdvb2dsZS5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYXRfaGFzaCI6IkJBSW55TjN2MS1ZejNLQnJUMVo0ckEiLCJuYW1lIjoiQnJpYW4gRGF1Z2hlcnR5IiwicGljdHVyZSI6Imh0dHBzOi8vbGgzLmdvb2dsZXVzZXJjb250ZW50LmNvbS9hLS9BT2gxNEdnenAyTXNGRGZvbVdMX3VDemRYUWNzeVM3ZGtxTE5ybk90S0QzVXNRPXM5Ni1jIiwiZ2l2ZW5fbmFtZSI6IkJyaWFuIiwiZmFtaWx5X25hbWUiOiJEYXVnaGVydHkiLCJsb2NhbGUiOiJlbiIsImlhdCI6MTYzODk5MTYzOCwiZXhwIjoxNjM4OTk1MjM4LCJqdGkiOiI5YmRkZjE1YWFiNzE2ZDhjYmJmNDYwMmM1YWM3YzViN2VhMDQ5OTA5In0.K3EA-3Adw5HA7O8nJVCsX1HmGWxWzYk3P7ViVBb4H4BoT2-HIgxKlx1mi6jSxIUJGEekjw9MC-nL1B9Asgv1vXTMgoGaNna0UoEHYitySI23E5jaMkExkTSLtxI-ih2tJrA2ggfA9Ekj-JFiMc6MuJnwcfBTlsYWRcZOYVw3QpdTZ_VYfhUu-yERAElZCjaAyEXLtVQegRe-ymScra3r9S92TA33ylMb3WDTlfmDpWL0CDdDzby2asXYpl6GQ7SdSj64s49Yw6mdGELZn5WoJqG7Zr2KwIGXJuSxEo-wGbzxNK-mKAiABcFpYP4KHPEUgYyz3n9Vqn2Tfrgp-g65BQ",
    "session_state": {
      "extraQueryParams": {
        "authuser": "0"
      }
    },
    "first_issued_at": 1638991637982,
    "expires_at": 1638995236982,
    "idpId": "google"
  }

Dane logowania do Google Identity Services

Biblioteka Google Identity Services zwraca:

  • token dostępu, gdy jest używany do autoryzacji:

    {
      "access_token": "ya29.A0ARrdaM_LWSO-uckLj7IJVNSfnUityT0Xj-UCCrGxFQdxmLiWuAosnAKMVQ2Z0LLqeZdeJii3TgULp6hR_PJxnInBOl8UoUwWoqsrGQ7-swxgy97E8_hnzfhrOWyQBmH6zs0_sUCzwzhEr_FAVqf92sZZHphr0g",
      "token_type": "Bearer",
      "expires_in": 3599,
      "scope": "https://www.googleapis.com/auth/calendar.readonly"
    }
    
  • lub token tożsamości używany do uwierzytelniania:

    {
      "clientId": "538344653255-758c5h5isc45vgk27d8h8deabovpg6to.apps.googleusercontent.com",
      "credential": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImMxODkyZWI0OWQ3ZWY5YWRmOGIyZTE0YzA1Y2EwZDAzMjcxNGEyMzciLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJuYmYiOjE2MzkxNTcyNjQsImF1ZCI6IjUzODM0NDY1MzI1NS03NThjNWg1aXNjNDV2Z2syN2Q4aDhkZWFib3ZwZzZ0by5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbSIsInN1YiI6IjExNzcyNjQzMTY1MTk0MzY5ODYwMCIsIm5vbmNlIjoiZm9vYmFyIiwiaGQiOiJnb29nbGUuY29tIiwiZW1haWwiOiJkYWJyaWFuQGdvb2dsZS5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYXpwIjoiNTM4MzQ0NjUzMjU1LTc1OGM1aDVpc2M0NXZnazI3ZDhoOGRlYWJvdnBnNnRvLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwibmFtZSI6IkJyaWFuIERhdWdoZXJ0eSIsInBpY3R1cmUiOiJodHRwczovL2xoMy5nb29nbGV1c2VyY29udGVudC5jb20vYS0vQU9oMTRHZ3pwMk1zRkRmb21XTF91Q3pkWFFjc3lTN2RrcUxOcm5PdEtEM1VzUT1zOTYtYyIsImdpdmVuX25hbWUiOiJCcmlhbiIsImZhbWlseV9uYW1lIjoiRGF1Z2hlcnR5IiwiaWF0IjoxNjM5MTU3NTY0LCJleHAiOjE2MzkxNjExNjQsImp0aSI6IjRiOTVkYjAyZjU4NDczMmUxZGJkOTY2NWJiMWYzY2VhYzgyMmI0NjUifQ.Cr-AgMsLFeLurnqyGpw0hSomjOCU4S3cU669Hyi4VsbqnAV11zc_z73o6ahe9Nqc26kPVCNRGSqYrDZPfRyTnV6g1PIgc4Zvl-JBuy6O9HhClAK1HhMwh1FpgeYwXqrng1tifmuotuLQnZAiQJM73Gl-J_6s86Buo_1AIx5YAKCucYDUYYdXBIHLxrbALsA5W6pZCqqkMbqpTWteix-G5Q5T8LNsfqIu_uMBUGceqZWFJALhS9ieaDqoxhIqpx_89QAr1YlGu_UO6R6FYl0wDT-nzjyeF5tonSs3FHN0iNIiR3AMOHZu7KUwZaUdHg4eYkU-sQ01QNY_11keHROCRQ",
      "select_by": "user"
    }
    

Odpowiedź dotycząca nieprawidłowego tokena

Przykład odpowiedzi Google podczas próby wysłania żądania do interfejsu API przy użyciu wygasłego, odwołanego lub nieprawidłowego tokena dostępu:

Nagłówki odpowiedzi HTTP

  www-authenticate: Bearer realm="https://accounts.google.com/", error="invalid_token"

Treść odpowiedzi

  {
    "error": {
      "code": 401,
      "message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
      "errors": [
        {
          "message": "Invalid Credentials",
          "domain": "global",
          "reason": "authError",
          "location": "Authorization",
          "locationType": "header"
        }
      ],
      "status": "UNAUTHENTICATED"
    }
  }