Migracja do usług Google Identity

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

Omówienie

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

Ten przewodnik zawiera instrukcje migracji z tych bibliotek do biblioteki usług tożsamości Google.

Postępując zgodnie z tym przewodnikiem:

  • Wycofać bibliotekę platformy z biblioteki usług tożsamości,
  • jeśli korzystasz z biblioteki klienta interfejsu API, usuń wycofany moduł gapi.auth2, jego metody i obiekty, zastępując je odpowiednikami usług tożsamości.

Aby dowiedzieć się, co zmieniło się w bibliotece JavaScript usług tożsamości, przeczytaj omówienie i zasady działania użytkowników.

Jeśli szukasz uwierzytelniania podczas rejestracji użytkowników i logowania się, zapoznaj się z artykułem Migracja z logowania przez Google.

Określanie procesu autoryzacji

Dostępne są 2 procesy autoryzacji użytkowników: niejawny i kod autoryzacji.

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

Jeśli Twoja aplikacja internetowa korzysta z procedury niejawnej:

Oznaczenia aplikacji internetowej korzystają z procedury kodu autoryzacji:

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

Wybierz proces autoryzacji

Przed rozpoczęciem migracji należy ustalić, czy kontynuowanie bieżącego procesu czy przejście na inny proces najlepiej spełnia Twoje potrzeby.

Zapoznaj się z informacjami o wybieraniu procesu autoryzacji, aby poznać kluczowe różnice i wady i zalety.

W większości przypadków zalecamy użycie kodu autoryzacji, ponieważ zapewnia on najwyższy poziom bezpieczeństwa użytkowników. Wdrożenie tego procesu ułatwia też dodanie do platformy nowych funkcji offline, takich jak pobieranie aktualizacji powiadamiających użytkowników o ważnych zmianach w ich kalendarzach, zdjęciach, subskrypcjach itp.

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

.

Uwierzytelnienie bezpośrednie

Uzyskaj token dostępu do użycia w przeglądarce, gdy użytkownik jest obecny.

Przykładowe przepływy pośrednie pokazują aplikacje internetowe przed i po migracji do usług tożsamości.

Przepływ kodu autoryzacji

Wydany przez Google kod autoryzacji dla każdego użytkownika jest dostarczany na Twoją platformę backendu, gdzie jest następnie wymieniany na token dostępu i token odświeżania.

Przykładowe kody przepływu autoryzacji: pokazuje aplikacje internetowe przed i po migracji do usług tożsamości.

W tym przewodniku postępuj zgodnie z pogrubionymi instrukcjami dodawania, usuwania, aktualizowania i zastępowania dotychczasowych funkcji.

Zmiany w przeglądarce

W tej sekcji opisujemy zmiany, które wprowadzisz w aplikacji internetowej w przeglądarce po przejściu do biblioteki JavaScript usług tożsamości Google.

Identyfikacja kodu i testowanie

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

W przypadku dużych lub złożonych aplikacji wykrycie całego kodu spowodowanego wycofaniem modułu gapi.auth2 może być trudne. Aby zarejestrować w konsoli obecne użycie, które wkrótce zostanie wycofane, ustaw wartość pliku cookie G_AUTH2_MIGRATION na informational. Opcjonalnie dodaj dwukropek, a następnie parę klucz-wartość, aby zapisać także pamięć sesji. Gdy się zalogujesz i odbierzesz dane logowania, możesz wysłać zebrane logi do backendu do późniejszej analizy. 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. Pozwala to przetestować zachowanie po wycofaniu aplikacji przed datą egzekwowania.

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

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

Aby zminimalizować wpływ użytkownika, zalecamy utworzenie pliku cookie lokalnie podczas programowania i testowania, zanim użyjesz go w środowiskach produkcyjnych.

Biblioteki i moduły

Moduł gapi.auth2 służy do zarządzania uwierzytelnianiem użytkowników podczas logowania i domyślnym procesem autoryzacji, zastępowaniem tego wycofanego modułu oraz jego obiektami i metodami biblioteką usług tożsamości Google.

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ą polecenia gapi.load('auth2', function).

Biblioteka usług Google Identity zastępuje korzystanie z modułu gapi.auth2. Możesz nadal bezpiecznie używać modułu gapi.client z biblioteki klienta interfejsu API Google dla JavaScriptu i korzystać z automatycznego tworzenia wywoływanych 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.

Więcej informacji o tym, jak uwierzytelnianie użytkowników korzysta z plików cookie, i o tym, jak Google wykorzystuje pliki cookie w innych usługach Google, znajdziesz w artykułach Migracja z logowania się przez Google.

Dane uwierzytelniające

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

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

Uwierzytelnienie bezpośrednie

Rozdziel uwierzytelnianie użytkowników i autoryzację przez usunięcie obsługi profili użytkowników z przepływów autoryzacji.

Usuń te materiały referencyjne klienta JavaScript związane z logowaniem przez Google:

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 logowania uzyskanych przez bezpośrednie wywołania punktów końcowych Google OAuth 2.0 z poziomu platformy backendu lub przez biblioteki działające na bezpiecznym serwerze na platformie, takiej jak klient Node.js interfejsów API Google.

Stan sesji

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

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

Usuń te materiały referencyjne 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 aplikację internetową, aby zainicjować klienta tokena dla przepływu kodu autoryzacji lub autoryzacji.

Usuń te materiały referencyjne klienta JavaScript związane z logowaniem przez Google:

Obiekty:

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

Metody:

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

Uwierzytelnienie bezpośrednie

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

Zastąp pliki referencyjne klienta JavaScript funkcji logowania przez Google usługami Google Identity:

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ą, zgodnie z przykładem dotyczącym inicjowania klienta kodu.

W przypadku przełączenia z domyślnej na tryb kodu autoryzacji:

Usuń Dokumentacja klienta JavaScript 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, generuje żądanie, które powoduje, że token dostępu jest zwracany bezpośrednio do przeglądarki użytkownika za pomocą przepływu niejawnego lub na platformę backendu po zamianie kodu autoryzacji użytkownika na token dostępu i odświeżanie tokena.

Uwierzytelnienie bezpośrednie

Tokeny dostępu można uzyskać i wykorzystywać w przeglądarce, gdy użytkownik jest zalogowany i ma aktywną sesję z Google. W trybie poufnym gest użytkownika musi poprosić o token dostępu, nawet jeśli wcześniej nastąpiło żądanie.

Zastąp pliki referencyjne klienta JavaScript usługi logowania Google: usługami Google Identity:

Metody:

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

Dodaj link lub przycisk, który wywoła metodę requestAccessToken(), by rozpocząć wyskakujące okienko z prośbą o przekazanie tokena dostępu lub uzyskanie nowego tokena, gdy istniejący token wygaśnie.

Zaktualizuj bazę kodu na:

  • Aktywuj przepływ tokena OAuth 2.0 za pomocą requestAccessToken().
  • Wspieraj przyrostową autoryzację przy użyciu requestAccessToken i OverridableTokenClientConfig, aby oddzielić jedno żądanie z wielu zakresów do wielu mniejszych żądań.
  • Poproś o nowy token, gdy istniejący token wygaśnie lub zostanie unieważniony.

Praca z wieloma zakresami może wymagać wprowadzenia zmian strukturalnych w bazie danych, aby żądać dostępu do zakresów tylko wtedy, gdy są one konieczne, a nie wszystkie naraz. Jest to nazywane przyrostową autoryzacją. Każde żądanie powinno zawierać jak najmniejszą liczbę zakresów, a najlepiej jeden. Więcej informacji o aktualizowaniu aplikacji na potrzeby przyrostowej autoryzacji znajdziesz w artykule na temat obsługiwania zgody użytkownika.

Po wygaśnięciu tokena dostępu moduł gapi.auth2 automatycznie otrzymuje nowy, prawidłowy token dostępu aplikacji internetowej. Aby zwiększyć bezpieczeństwo użytkowników, ten proces automatycznego odświeżania tokenów nie jest obsługiwany przez bibliotekę usług Google Identity. Twoja aplikacja internetowa musi zostać zaktualizowana, aby wykrył token dostępu, który wygasł, i poprosić o nowy. Więcej informacji znajdziesz w sekcji dotyczącej obsługi tokenów.

Przepływ kodu autoryzacji

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

Więcej informacji o tym, jak odpowiadać na prośby o wygasły lub unieważniony token dostępu, znajdziesz w sekcji poniżej.

Obsługa tokenów

Dodaj obsługę błędów, aby wykrywać nieudane wywołania interfejsu API Google, w których używany jest wygasły lub unieważniony token dostępu, oraz aby poprosić o nowy, prawidłowy token dostępu.

Gdy używany jest nieaktualny lub unieważniony token dostępu, interfejsy API Google zwracają 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 krótko i często są ważne tylko przez kilka minut.

Unieważnienie tokena

Właściciel konta Google może w każdej chwili cofnąć swoją zgodę. Spowoduje to unieważnienie istniejących tokenów dostępu i tokenów odświeżania. Dostęp do platformy można anulować za pomocą revoke() lub za pomocą konta Google.

Zastąp pliki referencyjne klienta JavaScript usługi logowania Google: usługami Google Identity:

Metody:

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

Wywołaj metodę revoke, gdy użytkownik usunie swoje konto z Twojej platformy lub chce usunąć zgodę na udostępnianie danych Twojej aplikacji.

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

Przed wystawieniem tokena dostępu do aplikacji istniejąca i aktywna sesja Google musi prosić użytkownika o zgodę na wykorzystanie danych oraz rejestrować wynik. Użytkownik może być zmuszony do zalogowania 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 lub bezpośrednio w przeglądarce lub systemie operacyjnym. Zalecamy dodanie do witryny funkcji Zaloguj się przez Google, aby rozpocząć aktywną sesję między kontem Google a przeglądarką, kiedy użytkownik po raz pierwszy otworzy aplikację. Pozwala to uzyskać następujące korzyści:

  • Minimalizuje liczbę prób zalogowania się użytkownika przez żądanie tokena dostępu inicjuje proces logowania 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, jeśli na Twojej platformie nie ma systemu zarządzania kontami użytkowników.
  • wyszukać i powiązać konto Google z lokalnym kontem użytkownika na swojej platformie, co pozwoli zminimalizować liczbę zduplikowanych kont.
  • Po utworzeniu nowego konta lokalnego okno dialogowe i proces rejestracji mogą być wyraźnie oddzielone od okien i procesów uwierzytelniania użytkowników, co zmniejszy liczbę wymaganych kroków i poprawi współczynnik porzuceń.

Po zalogowaniu się, ale przed wydaniem tokena dostępu użytkownicy muszą wyrazić zgodę na aplikację w żądanych zakresach.

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ą zatwierdzanie i 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. W zależności od opcji wybranych przez użytkownika Twoja aplikacja włącza wybrane funkcje w zależności od konkretnego zakresu.

Uwierzytelnienie bezpośrednie

Zastąp pliki referencyjne klienta JavaScript funkcji logowania przez Google usługami Google Identity:

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ń Dokumentacja klienta JavaScript Logowania przez Google:

Metody:

  • GoogleUser.getAuthResponse()

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

Przepływ kodu autoryzacji

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

Zaktualizuj swoją 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 swoją platformę, aby selektywnie włączać lub wyłączać funkcje, w zależności od poszczególnych zakresów, które użytkownik zatwierdził. Aby to zrobić, postępuj zgodnie z instrukcjami autoryzacji przyrostowej 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 uruchomionego w przeglądarce za pomocą wyskakującego okienka dotyczącego zgody użytkownika.

Moduł gapi.auth2 jest ładowany automatycznie i używany przez usługę 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

Protokół OAuth 2.0 dla aplikacji internetowych po stronie klienta działających w przeglądarce za pomocą 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

Protokół OAuth 2.0 dla aplikacji internetowych po stronie klienta, który działa w przeglądarce przy użyciu przekierowań do Google na potrzeby zgody użytkownika.

Ten przykład pokazuje bezpośrednie wywołania punktów końcowych OAuth 2.0 Google 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 pokazuje tylko bibliotekę JavaScript usługi Google Identity, używając modelu tokena i wyskakującego okienka dotyczącego zgody użytkownika. Jej celem jest zilustrowanie minimalnej liczby czynności wymaganych do skonfigurowania klienta, żądania i uzyskania tokena dostępu oraz wywołania 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>

Asynchroniczne/oczekujące GAPI

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

Obietnice, asynchroniczne i oczekujące są używane do wymuszania kolejności wczytywania bibliotek 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”, jeśli brakuje tokena dostępu przy pierwszym wczytaniu strony lub później po wygaśnięciu tokena dostępu.

<!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 przy użyciu modelu tokena, usunąć moduł gapi.auth2 i wywołać interfejs API za pomocą biblioteki klienta interfejsu API Google dla JavaScriptu.

Zmienne są używane do egzekwowania 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 wczytaniu strony, a gdy chcą odświeżyć informacje o kalendarzu, ponownie.

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

Wyskakujące okienko UX usługi Google Identity Service może korzystać z przekierowania URL do zwracania kodu autoryzacji bezpośrednio do punktu końcowego tokena backendu lub do modułu obsługi wywołania zwrotnego JavaScriptu w przeglądarce użytkownika, który przekazuje odpowiedź na Twoją platformę. W obu przypadkach proces backendu kończy się za pomocą protokołu 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ące na platformie backendu z przekierowaniem 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 przypadku aplikacji internetowych do wysyłania kodu autoryzacji z przeglądarki użytkownika do platformy backendu. Zgoda użytkownika jest przetwarzana 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

Wyskakujące okienko GIS – UX

Ten przykład pokazuje tylko bibliotekę JavaScript usługi tożsamości Google, używając modelu kodu autoryzacji – dla wyskakującego okienka z prośbą o zgodę użytkownika i dla modułu obsługi wywołania zwrotnego w celu odebrania kodu autoryzacji od Google. Jej celem jest zilustrowanie minimalnej liczby czynności wymaganych do skonfigurowania klienta, uzyskania zgody i wysłania kodu autoryzacji do platformy 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=' + 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>

Przekierowanie GIS

Model kodu autoryzacji obsługuje tryby UX wyskakującego i przekierowywania, aby wysyłać kod autoryzacji poszczególnych użytkowników do punktu końcowego hostowanego przez Twoją platformę. Tryb 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. W jej ramach skonsolidowano i zastąpiono funkcje dostępne 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ślnymi 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 bibliotekami starego oprogramowania Klienta JavaScript używanego do logowania w Google oraz biblioteką Nowa usługa tożsamości Google oraz uwagami, które zawierają dodatkowe informacje i czynności, które należy wykonać podczas migracji.

Stara wersja Nowy Uwagi
Obiekt GoogleAuth i powiązane z nim metody:
GoogleAuth.attachClickHandler() Usuń
GoogleAuth.currentUser.get() Usuń
GoogleAuth.currentUser.listen(). Usuń
GoogleAuth.disconnect() google.accounts.oauth2.revoke Zastąp stary z nowym. Może to też nastąpić na stronie https://myaccount.google.com/permissions
GoogleAuth.grantOfflineAccess() Usuń go, postępując zgodnie z instrukcjami dotyczącymi kodu autoryzacji.
GoogleAuth.isSignedIn.get() Usuń
GoogleAuth.isSignedIn.listen() Usuń
GoogleAuth.signIn() Usuń
GoogleAuth.signOut() Usuń
GoogleAuth.then(), Usuń
Obiekt GoogleUser i powiązane z nim metody:
GoogleUser.disconnect() google.accounts.id.revoke Zastąp stary z nowym. Może to też nastąpić na stronie https://myaccount.google.com/permissions
GoogleUser.getAuthResponse() requestCode() lub requestAccessToken() Zastąp stare stare
GoogleUser.getBasicProfile() Usuń. Zamiast tego użyj tokena tożsamości. Zobacz Migracja z logowania przez Google.
GoogleUser.getGrantedScopes() hasGrantedanyScope() Zastąp stare stare
GoogleUser.getHostDomain() Usuń
GoogleUser.getId() Usuń
GoogleUser.grantOfflineAccess() Usuń go, postępując zgodnie z instrukcjami dotyczącymi kodu autoryzacji.
GoogleUser.grant() Usuń
GoogleUser.hasGrantedScopes() hasGrantedanyScope() Zastąp stare stare
GoogleUser.isSignedIn() Usuń
GoogleUser.reloadAuthResponse() requestAccessToken() Usuń stare. Wywołaj nowy, aby wygasł lub unieważniono token dostępu.
gapi.auth2 i powiązane metody:
obiekt gapi.auth2.AuthorizeConfig TokenClientConfig lub CodeClientConfig Zastąp stare stare
obiekt gapi.auth2.AuthorizeResponse Usuń
obiekt gapi.auth2.AuthResponse Usuń
gapi.auth2.authorized() requestCode() lub requestAccessToken() Zastąp stare stare
gapi.auth2.ClientConfig() TokenClientConfig lub CodeClientConfig Zastąp stare stare
gapi.auth2.getAuthInstance() Usuń
gapi.auth2.init() initTokenClient() lub initCodeClient() Zastąp stare stare
obiekt gapi.auth2.OfflineAccessOptions Usuń
obiekt gapi.auth2.SignInOptions Usuń
gapi.signin2 i powiązane metody:
gapi.signin2.render() Usuń. Wczytywanie elementu g_id_signin lub wywołania JS na żądanie google.accounts.id.renderButton HTML powoduje zalogowanie się użytkownika na koncie 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 w ramach jednej odpowiedzi zwracają token dostępu OAuth 2.0 oraz token identyfikatora OpenID Connect.

Przykładowa odpowiedź zawierająca access_token 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 uwierzytelniające w usługach Google Identity

Biblioteka usług Google Identity zwraca:

  • albo token dostępu używany podczas 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 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ź Google przy próbie wysłania żądania do 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"
    }
  }