警告:这些数据是根据 Google 用户数据政策提供的。请查看并遵守该政策。否则,可能会导致项目或帐号被暂停。

Migracja do usług Google Identity

Opis

Aby uzyskać token dostępu użytkownika na potrzeby wywołań interfejsów API Google, Google oferuje wiele bibliotek JavaScript:

Ten przewodnik zawiera instrukcje dotyczące przenoszenia tych bibliotek do biblioteki usług tożsamości Google.

Postępując zgodnie z tym przewodnikiem, wykonaj te czynności:

  • zastąpić bibliotekę wycofywanych platform biblioteką tożsamości
  • jeśli używasz biblioteki klienta interfejsu API, usuń wycofany moduł gapi.auth2 i jego metody oraz obiekty, zastępując je odpowiednikami usług tożsamości.

Opis zmian w bibliotece JavaScript usług Identity Identity znajdziesz w omówieniu oraz działaniu autoryzacji użytkowników w celu zapoznania się z kluczowymi terminami i ich pojęciami.

Jeśli szukasz informacji związanych z uwierzytelnianiem rejestracji użytkowników i logowania się, zobacz artykuł Migracja z logowania przez Google.

Określ proces autoryzacji

Są 2 następujące procesy autoryzacji użytkownika: niejawny i kod autoryzacji.

Sprawdź aplikację internetową, aby zidentyfikować typ przepływu autoryzacji, który jest obecnie używany.

Oznacza, że Twoja aplikacja internetowa korzysta z przepływu domyślnego:

Oznacza, że Twoja aplikacja internetowa wykorzystuje proces kodu autoryzacji:

W niektórych przypadkach baza kodu może obsługiwać oba schematy.

Wybierz proces autoryzacji

Przed rozpoczęciem migracji musisz zdecydować, czy chcesz kontynuować obecny proces, czy zastosować inny proces.

Sprawdź, jak wybrać przepływ autoryzacji, aby poznać główne różnice i zależności między tymi 2 procesami.

W większości przypadków zalecamy użycie kodu autoryzacji, ponieważ zapewnia on najwyższy poziom bezpieczeństwa użytkowników. Wdrożenie tej procedury ułatwi też platformie dodanie nowych funkcji offline, takich jak pobieranie powiadomień o istotnych zmianach w kalendarzu, zdjęciach, subskrypcjach itp.

Wybierz metodę autoryzacji, korzystając z poniższych selektorów.

Przepływ niejawny

Uzyskiwanie tokena dostępu do użycia w przeglądarce przez użytkownika.

Przykłady przepływu domyślnego pokazują aplikacje internetowe przed migracją i do usług tożsamości.

Przepływ kodu autoryzacji

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

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

Korzystając z tego przewodnika, wykonaj pogrubione instrukcje dotyczące dodawania, usuwania, aktualizowania i zastępowania istniejących funkcji.

Zmiany w przeglądarce

W tej sekcji sprawdzisz zmiany w aplikacji internetowej uruchomionej w przeglądarce, gdy przeprowadzisz migrację do biblioteki JavaScript usług tożsamości Google.

Identyfikacja kodu i testowanie

Plik cookie debugowania może pomóc w znalezieniu kodu, którego dotyczy problem, oraz przetestowaniu działania po wycofaniu.

W dużych lub złożonych aplikacjach znalezienie kodu, którego dotyczy zmiana, może być trudne. Aby zarejestrować w konsoli dotychczasowe wykorzystanie tej funkcji, ustaw wartość pliku cookie G_AUTH2_MIGRATION na informational. Opcjonalnie dodaj dwukropek, a następnie parę klucz-wartość, aby zapisać także dane w pamięci sesji. Po zalogowaniu się i otrzymaniu danych logowania wyślij je do backendu, aby przeprowadzić dalszą analizę. Na przykład informational:showauth2use zapisuje źródło i adres URL w kluczu pamięci sesji o nazwie showauth2use.

Aby zweryfikować działanie aplikacji, gdy moduł gapi.auth2 nie jest już wczytywany, ustaw wartość pliku cookie G_AUTH2_MIGRATION na enforced. Pozwoli to na przetestowanie działania po wycofaniu aplikacji przed datą wymuszenia.

Możliwe wartości pliku cookie G_AUTH2_MIGRATION:

  • enforced Nie wczytuj modułu gapi.auth2.
  • informational Loguj wykorzystanie wycofanej funkcji w konsoli JS. Gdy zostanie ustawiona opcjonalna nazwa klucza, zapisz też dane w pamięci sesji: informational:key-name.

Aby zminimalizować wpływ na użytkownika, najlepiej ustawić plik cookie lokalnie na etapie tworzenia i testowania, a następnie używać go w środowiskach produkcyjnych.

Biblioteki i moduły

Moduł gapi.auth2 zarządza uwierzytelnianiem użytkowników i logowaniem się przez autoryzację. Zastąp wycofany moduł oraz jego obiekty i metody biblioteką usług tożsamości Google.

Dodaj bibliotekę usług tożsamości do swojej aplikacji internetowej, umieszczając ją w dokumencie:

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

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

Biblioteka usług Google Identity zastępuje moduł gapi.auth2. Możesz nadal bezpiecznie korzystać z modułu gapi.client pochodzącego z Biblioteki klienta interfejsu API Google dla JavaScriptu i korzystać z automatycznego tworzenia możliwych do wywołania metod JS z dokumentu wykrywania, grupowania wielu wywołań interfejsu API i funkcji zarządzania CORS.

Pliki cookie

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

Szczegółowe informacje o tym, jak użytkownicy korzystają z plików cookie, znajdziesz w artykule Migracja z logowania Google, a w artykule o tym, jak Google korzysta z plików cookie w przypadku plików cookie w innych usługach Google.

Dane uwierzytelniające

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

Aby wyświetlić te zmiany, zobacz przykładowe dane logowania.

Przepływ niejawny

Uwierzytelnij użytkownika i autoryzuj go, usuwając obsługę profilu użytkownika z przepływów autoryzacji.

Usuń te odniesienia do klienta JavaScript związane z logowaniem przez Google:

Metody

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

Przepływ kodu autoryzacji

Usługa tożsamości dzieli dane logowania w przeglądarce na token tożsamości i token dostępu. Ta zmiana nie dotyczy danych logowania uzyskanych przez bezpośrednie wywołania punktów końcowych Google OAuth 2.0 na platformie backendu ani za pomocą bibliotek działających na bezpiecznym serwerze na Twojej platformie, takich jak klient Node.js dla interfejsów API Google.

Stan sesji

Wcześniej funkcja Logowanie przez Google pomagała zarządzać stanem zalogowania użytkownika za pomocą:

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

Usuń te odniesienia do klienta JavaScript związane z logowaniem 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 na potrzeby niejawnego lub kodu autoryzacji.

Usuń te odniesienia do klienta JavaScript związane z logowaniem przez Google:

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 według przykładu z przykładu inicjowania klienta tokena.

Zastąp odwołania klienta JavaScript do logowania przez Google usługami tożsamości Google:

Obiekty:

  • gapi.auth2.AuthorizeConfig: TokenClientConfig

Metody:

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

Parametry:

  • gapi.auth2.AuthorizeConfig.login_hintTokenClientConfig.hint.
  • gapi.auth2.GoogleUser.getHostedDomain()TokenClientConfig.hosted_domain.

Przepływ kodu autoryzacji

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

Po przejściu z domyślnej procedury na kod autoryzacji:

Usuń Dokumentacja klienta JavaScript używanego do logowania przez Google

Obiekty:

  • gapi.auth2.AuthorizeConfig

Metody:

  • gapi.auth2.init()

Parametry:

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

Żądanie tokena

Gest użytkownika, taki jak kliknięcie przycisku, powoduje wygenerowanie żądania, które powoduje zwrócenie tokena dostępu bezpośrednio do przeglądarki użytkownika (ukryte jest to pośrednio) lub do platformy backendu po zamianie kodu autoryzacji użytkownika na token dostępu i odświeżenie.

Przepływ niejawny

Tokeny dostępu można uzyskać i używać w przeglądarce, gdy użytkownik jest zalogowany i ma aktywną sesję z Google. W trybie niejawnym wymaga się gestu użytkownika, aby zażądać tokena dostępu, nawet jeśli żądanie pochodziło od użytkownika.

Zastąp Odwołania do klientów JavaScript w funkcji logowania przez Google: Usługami tożsamości Google:

Metody:

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

Dodaj link lub przycisk, aby wywołać requestAccessToken(), aby rozpocząć wyskakujące okienko z żądaniem UX, aby zażądać tokena dostępu lub uzyskać nowy token, gdy istniejący token wygaśnie.

Zaktualizuj bazę kodu do:

  • Uruchom przepływ tokena OAuth 2.0 z użyciem requestAccessToken().
  • Wspieraj przyrostową autoryzację, używając requestAccessToken i OverridableTokenClientConfig do rozdzielania jednego żądania na wiele zakresów na kilka mniejszych żądań.
  • Poproś o nowy token, gdy istniejący token wygaśnie lub zostanie unieważniony.

Praca z wieloma zakresami może wymagać zmian strukturalnych w bazie kodu, aby żądać dostępu do zakresów tylko wtedy, gdy są potrzebne, a nie za jednym razem, czyli tzw. autoryzacji przyrostowej. Każde żądanie powinno zawierać jak najmniejszy zakres, a najlepiej najlepiej 1 zakres. Dowiedz się, jak odpowiadać na pytania użytkowników, jak zaktualizować aplikację, by zwiększyć autoryzację.

Po wygaśnięciu tokena dostępu moduł gapi.auth2 automatycznie otrzymuje nowy, prawidłowy token dostępu do aplikacji internetowej. Ze względów bezpieczeństwa ten proces automatycznego odświeżania tokenów nie jest obsługiwany przez bibliotekę usług Google Identity. Musisz zaktualizować swoją aplikację internetową, aby wykryła token dostępu, który wygasł, i poprosić o nowy. Więcej informacji znajdziesz w sekcji poświęconej obsłudze tokenów.

Przepływ kodu autoryzacji

Dodaj link lub przycisk, by wywołać kod requestCode() i poprosić Google o kod autoryzacji. Przykład znajdziesz w artykule Wywoływanie przepływu kodu OAuth 2.0.

Aby dowiedzieć się, jak odpowiedzieć na wygasły lub unieważniony token dostępu, przeczytaj sekcję poniżej dotyczącą obsługi tokenów.

Obsługa tokenów

Dodaj obsługę błędów, aby wykrywać nieudane wywołania interfejsu API Google, gdy token dostępu wygasł lub unieważniony, i poprosić o nowy, prawidłowy token dostępu.

Gdy używany jest nieważny token dostępu, interfejs API Google zwraca kod stanu HTTP 401 Unauthorized i komunikat o błędzie invalid_token. Przykład znajdziesz w artykule Nieprawidłowa odpowiedź tokena.

wygasłe tokeny,

Tokeny dostępu są ważne tylko przez kilka minut.

Unieważnienie tokena

Właściciel konta Google może w każdej chwili cofnąć zgodę. W ten sposób istniejące tokeny dostępu zostaną unieważnione. Unieważnienie może zostać aktywowane z Twojej platformy przy użyciu revoke() lub za pomocą konta Google.

Zastąp Odwołania do klientów JavaScript w funkcji logowania przez Google: Usługami tożsamości Google:

Metody:

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

Wywołaj revoke, gdy użytkownik usunie swoje konto z Twojej platformy lub poprosi o zgodę na udostępnianie danych Twojej aplikacji.

Google wyświetla użytkownikowi okno zgody, gdy aplikacja internetowa lub platforma backendu prosi o token dostępu. Zobacz okna z prośbą o zgodę na wykorzystanie danych wyświetlane użytkownikom przez Google.

Zanim otrzymasz token dostępu do aplikacji, musisz przesłać nam istniejącą i aktywną sesję Google, aby uzyskać zgodę użytkownika i zapisać wynik. Może to oznaczać, że użytkownik musi zalogować się na konto Google, jeśli istniejąca sesja nie została jeszcze utworzona.

Logowanie użytkownika

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

  • Minimalizuje liczbę konieczności logowania się przez użytkownika, wysyłając prośbę o token dostępu inicjujący proces logowania się na konto Google, jeśli aktywna sesja jeszcze nie istnieje.
  • Użyj wartości pola dane logowania tokena JWT email jako wartości parametru hint w obiektach CodeClientConfig lub TokenClientConfig. Jest to szczególnie przydatne, gdy Twoja platforma nie ma systemu zarządzania kontami użytkowników.
  • Sprawdź konto Google i powiąż z nim istniejące konto użytkownika lokalnego, aby zminimalizować zduplikowane konta na tej platformie.
  • Po utworzeniu nowego konta lokalnego Twoje okna dialogowe i proces rejestracji można wyraźnie oddzielić od dialogów i przepływów uwierzytelniania użytkowników, zmniejszając liczbę wymaganych kroków i poprawiając współczynnik porzuceń.

Po zalogowaniu się i przed wydaniem tokena dostępu użytkownicy muszą wyrazić zgodę na wymienione poniżej zakresy aplikacji.

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

Uprawnienia szczegółowe umożliwiają użytkownikom zatwierdzanie lub odrzucanie poszczególnych zakresów. Gdy prosisz o dostęp do wielu zakresów, każdy z nich jest przyznawany lub odrzucany niezależnie od pozostałych. Na podstawie Twojego wyboru aplikacji aplikacja włącza wybrane funkcje zależne od zakresu.

Przepływ niejawny

Zastąp odwołania klienta JavaScript do logowania przez Google usługami tożsamości Google:

Obiekty:

  • gapi.auth2.AuthorizeResponse: TokenClient.TokenResponse
  • gapi.auth2.AuthResponse: TokenClient.TokenResponse

Metody:

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

Usuń Odwołania do klienta JavaScriptu do logowania przez Google:

Metody:

  • GoogleUser.getAuthResponse()

Zaktualizuj aplikację internetową za pomocą hasGrantedAllScopes() i hasGrantedAnyScope(), postępując zgodnie z tym przykładem szczegółowych uprawnień.

Przepływ kodu autoryzacji

Zaktualizuj lub dodaj punkt końcowy kodu autoryzacji do platformy backendu, postępując zgodnie z instrukcjami obsługiwania kodu autoryzacji.

Zaktualizuj platformę, wykonując czynności opisane w przewodniku Używanie modelu kodu, aby zweryfikować żądanie i uzyskać token dostępu oraz token odświeżania.

Zaktualizuj platformę, aby wybiórczo włączyć lub wyłączyć funkcje, w zależności od indywidualnych zakresów zatwierdzonych przez użytkownika. Aby to zrobić, wykonaj instrukcje dotyczące przyrostowej autoryzacji oraz badania zakresów dostępu przyznanych przez użytkownika.

Przykłady przepływu pośredniego

Stary sposób

Biblioteka klienta GAPI

Przykład biblioteki klienta interfejsu API Google dla JavaScriptu uruchamianej w przeglądarce za pomocą wyskakującego okienka z prośbą o zgodę użytkownika.

Moduł gapi.auth2 jest wczytywany automatycznie i używany przez usługę gapi.client.init(), więc 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

Protokół OAuth 2.0 dla aplikacji internetowych po stronie klienta uruchomiony w przeglądarce przy użyciu wyskakującego okienka dotyczącego zgody użytkownika.

Moduł gapi.auth2 jest ładowany 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 w przypadku aplikacji internetowych po stronie klienta działających w przeglądarce z wykorzystaniem przekierowań do Google, by uzyskać zgodę użytkownika.

Ten przykład pokazuje bezpośrednie wywołania punktów końcowych Google OAuth 2.0 w przeglądarce użytkownika i nie używa 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>

Nowy sposób

Tylko GIS

Ten przykład to tylko biblioteka JavaScript usługi tożsamości Google korzystając z modelu tokena i wyskakujące okienko z prośbą o zgodę użytkownika. Ilustracja zawiera minimalną liczbę kroków wymaganych do skonfigurowania klienta, żądania i uzyskania tokena dostępu oraz wywoływania interfejsu API Google.

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

Synchronizacja/oczekiwanie na GAPI

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 Google API dla JavaScriptu.

Obietnice, asynchroniczne i oczekujące są używane do wymuszania zamówienia wczytywania biblioteki oraz do wykrywania i ponawiania błędów autoryzacji. Wywołanie interfejsu API jest wykonywane dopiero po udostępnieniu prawidłowego tokena dostępu.

Użytkownicy powinni nacisnąć przycisk &Pokaż kalendarz&#39, gdy brakuje tokena dostępu podczas pierwszego wczytywania strony lub po upływie tego okresu.

<!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ę usługi Google Identity za pomocą modelu tokena, usunąć moduł gapi.auth2 i wywołać interfejs API za pomocą Biblioteki klienta Google API dla JavaScriptu.

Zmienne są używane do wymuszania kolejności wczytywania biblioteki. 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 wczytaniu strony oraz ponownie, gdy chcą odświeżyć swoje 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 an 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

Wyskakujące okienko z biblioteką usługi tożsamości Google może użyć przekierowania adresu URL, aby zwrócić kod autoryzacji bezpośrednio do punktu końcowego tokena backendu, lub modułu obsługi wywołania zwrotnego JavaScriptu uruchomionego w przeglądarce użytkownika, który przekazuje odpowiedź na Twoją platformę. W każdym z tych przypadków platforma backendu realizuje proces OAuth 2.0, aby uzyskać prawidłowy token odświeżania i dostępu.

Stary sposób

Aplikacje internetowe po stronie serwera

Logowanie przez Google w aplikacjach po stronie serwera działających w platformie backendu przy użyciu 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 za pomocą przekierowania

Używanie protokołu OAuth 2.0 w aplikacjach internetowych do wysyłania kodu autoryzacji z przeglądarki użytkownika na platformę backendu. Zgoda użytkownika jest przetwarzana przez przekierowanie przeglądarki użytkownika 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

Wyskakujące okienko GIS – UX

Ten przykład pokazuje tylko bibliotekę JavaScript usługi tożsamości Google za pomocą modelu kodu autoryzacji w wyskakującym okienku umożliwiającym wyrażenie zgody przez aplikację i moduł obsługi wywołania zwrotnego w celu uzyskania kodu autoryzacji od Google. Jej celem jest zobrazowanie minimalnej liczby kroków do skonfigurowania klienta, uzyskania zgody i wysłania kodu autoryzacji do backendu.

<!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=' + 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>

Przekierowanie GIS – UX

Model kodu autoryzacji obsługuje tryb pop-u i przekierowania UX, by wysłać kod autoryzacji użytkownika do punktu końcowego hostowanego przez Twoją platformę. Tryb przekierowania UX jest widoczny tutaj:

<!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. Konsoliduje ona i zastępuje funkcje oraz funkcje dostępne w wielu różnych bibliotekach i modułach:

Czynności, 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 instrukcjami.
apis.google.com/js/client.js accounts.google.com/gsi/client Dodaj nową bibliotekę i przepływ kodu autoryzacji.

Krótki przewodnik po bibliotece

Porównanie obiektów i metod między biblioteką starego klienta kodu JavaScript logowania przez Google oraz nową biblioteką Google Identity Services i notatkami z dodatkowymi informacjami i działaniami, które należy podjąć podczas migracji.

Stara wersja Nowy Uwagi
Obiekty Google Authenticator i powiązane z nimi metody:
GoogleAuth.attachClickHandler(), Usuń
GoogleAuth.currentUser.get() Usuń
GoogleAuth.currentUser.listen() Usuń
GoogleAuth.disconnect() google.accounts.oauth2.revoke Zastąp stare nowym. Może to też nastąpić na stronie https://myaccount.google.com/permissions
GoogleAuth.grantOfflineAccess() Usuń zgodnie z procedurą kodu autoryzacji.
GoogleAuth.isSignedIn.get(), Usuń
GoogleAuth.isSignedIn.listen(). Usuń
GoogleAuth.signIn() Usuń
GoogleAuth.signOut() Usuń
GoogleAuth.after() Usuń
GoogleUser i powiązane metody:
GoogleUser.disconnect() google.accounts.id.revoke, Zastąp stare nowym. Może to też nastąpić na stronie https://myaccount.google.com/permissions
GoogleUser.getAuthResponse() requestCode() lub requestAccessToken() Zastąp stare nowym
GoogleUser.getBasicProfile(). Usuń. Zamiast niej użyj tokena tożsamości. Zobacz artykuł Migracja z Logowania przez Google.
GoogleUser.getGrantedScopes(), hasGrantedDowolnaScope() Zastąp stare nowym
GoogleUser.getHostedDomain(). Usuń
GoogleUser.getId(), Usuń
GoogleUser.grantOfflineAccess() Usuń zgodnie z procedurą kodu autoryzacji.
GoogleUser.grant() Usuń
GoogleUser.hasGrantedScopes(), hasGrantedDowolnaScope() Zastąp stare nowym
GoogleUser.isSignedIn(). Usuń
GoogleUser.reloadAuthResponse() requestAccessToken() Usuń stare. Wywołaj nowe, aby wygasły lub unieważniony token dostępu.
gapi.auth2 i powiązane metody:
Obiekt gapi.auth2.AuthorizeConfig TokenClientConfig lub CodeClientConfig Zastąp stare nowym
Obiekt gapi.auth2.AuthorizeResponse Usuń
Obiekt gapi.auth2.AuthResponse Usuń
gapi.auth2.authorize() requestCode() lub requestAccessToken() Zastąp stare nowym
gapi.auth2.ClientConfig() TokenClientConfig lub CodeClientConfig Zastąp stare nowym
gapi.auth2.getAuthInstance() Usuń
gapi.auth2.init() initTokenClient() lub initCodeClient() Zastąp stare nowym
Obiekt gapi.auth2.OfflineAccessOptions Usuń
Obiekt gapi.auth2.SignInOptions Usuń
gapi.signin2 i powiązane metody:
gapi.signin2.render() Usuń. Ładowanie elementu DOM elementu HTML g_id_signin lub wywołania JS w parametrze google.accounts.id.renderButton powoduje zalogowanie użytkownika na konto Google.

Przykładowe dane logowania

Istniejące dane logowania

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

Przykładowa odpowiedź zawierająca zarówno tag 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 usług tożsamości Google

Biblioteka Google Identity Services zwraca:

  • albo token dostępu 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 identyfikatora używany podczas 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"
  }

Nieprawidłowa odpowiedź tokena

Przykładowa odpowiedź od Google, gdy próbujesz wysłać żądanie interfejsu API przy użyciu nieważnego, unieważnionego 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"
    }
  }