Przegląd
Aby uzyskać token dostępu każdego użytkownika wywołujący interfejsy 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:
- Wycofać bibliotekę platformy z biblioteką usług tożsamości.
- jeśli używasz Biblioteki klienta API, usuń wycofany moduł
gapi.auth2
, jego metody i obiekty, zastępując je odpowiednikami usług tożsamości.
Opis zmian w bibliotece JavaScript usług tożsamości zawiera omówienie ogólnych informacji i sposobu działania autoryzacji użytkowników, w których opisaliśmy najważniejsze terminy i pojęcia.
Jeśli szukasz uwierzytelniania na potrzeby rejestracji i logowania użytkowników, zamiast tego przeczytaj artykuł Migracja z logowania przez Google.
Określ proces autoryzacji
Są 2 możliwe przepływy autoryzacji użytkowników: niejawny i kod autoryzacji.
Sprawdź aplikację internetową, aby dowiedzieć się, z jakiego typu procesu autoryzacji obecnie korzystasz.
Jeśli Twoja aplikacja internetowa korzysta z domyślnych instrukcji,
- Twoja aplikacja internetowa jest całkowicie oparta na przeglądarce i nie ma platformy backendu.
- Użytkownik musi być obecny, aby wywoływać interfejsy API Google. Aplikacja używa tylko tokenów dostępu i nie wymaga tokenów odświeżania.
- Twoja aplikacja internetowa wczytuje się:
apis.google.com/js/api.js
- Implementacja bazuje na protokole OAuth 2.0 dla aplikacji internetowych po stronie klienta.
- Twoja aplikacja używa modułów
gapi.client
lubgapi.auth2
dostępnych w bibliotece klienta interfejsu API Google dla języka JavaScript.
Jeśli Twoja aplikacja internetowa korzysta z procesu autoryzacji kodu:
Implementacja opiera się na:
Aplikacja jest wykonywana zarówno w przeglądarce użytkownika, jak i na platformie backendu.
Platforma backendu hostuje punkt końcowy kodu autoryzacji.
Platforma backendu wywołuje interfejsy Google API w imieniu użytkowników bez konieczności ich obecności w trybie offline.
Tokeny odświeżania są zarządzane i przechowywane przez platformę backendu.
W niektórych przypadkach baza kodu może obsługiwać oba te procesy.
Wybierz proces autoryzacji
Przed rozpoczęciem migracji musisz określić, czy chcesz kontynuować obecną procedurę, czy lepiej zastosować inną.
Zapoznaj się z procesem autoryzacji, aby poznać kluczowe różnice i wady i zalety obu procesów.
W większości przypadków zalecamy stosowanie kodu autoryzacji, ponieważ zapewnia on najwyższy poziom bezpieczeństwa użytkowników. Wdrożenie tej procedury ułatwi Twojej platformie dodawanie nowych funkcji offline, takich jak pobieranie aktualizacji w celu powiadamiania o istotnych zmianach w kalendarzu, zdjęciach, subskrypcjach itd.
Wybierz proces autoryzacji przy użyciu selektorów poniżej.
Uwierzytelnienie bezpośrednie
Uzyskaj token dostępu do użycia w przeglądarce, gdy użytkownik jest obecny.
Przykłady przepływu pośredniego: pokazuje aplikacje internetowe przed migracją do usług tożsamości i po ich zakończeniu.
Przepływ kodu autoryzacji
Google otrzymuje kod autoryzacji użytkownika wydany przez platformę backendu, gdzie jest on wymieniany na token dostępu i token odświeżania.
Przykłady przepływu kodu autoryzacji: wyświetlanie aplikacji internetowych przed migracją do usług tożsamości i po ich zakończeniu.
W tym przewodniku wykonaj pogrubione czynności, aby dodać, usunąć, zaktualizować lub zastąpić istniejące funkcje.
Zmiany w przeglądarce
W tej sekcji sprawdzisz zmiany, jakie wprowadzisz w aplikacji internetowej w przeglądarce podczas migracji do biblioteki JavaScript usług tożsamości Google.
Identyfikacja i testowanie kodu, którego dotyczy problem
Plik cookie debugowania może pomóc w zlokalizowaniu kodu, którego dotyczy problem, i przetestowaniu działania po wycofaniu.
W przypadku dużych lub złożonych aplikacji znalezienie kodu, którego dotyczy wycofanie modułu gapi.auth2
, może być trudne. Aby w konsoli zarejestrować dotychczasowe użycie, które zostanie wkrótce wycofane, ustaw wartość pliku cookie G_AUTH2_MIGRATION
na informational
. Opcjonalnie dodaj dwukropek, a następnie parę klucz-wartość, aby zapisać także dane sesji.
Gdy się zalogujesz i odbierzesz dane logowania, lub prześlij zebrane logi do backendu, aby przeanalizować je później. Na przykład informational:showauth2use
zapisuje źródło i adres URL w kluczu pamięci sesji o nazwie showauth2use
.
Aby sprawdzić działanie aplikacji, gdy moduł gapi.auth2
nie jest już wczytywany, ustaw wartość pliku cookie G_AUTH2_MIGRATION
na enforced
. Pozwala to przetestować działanie po wycofaniu z wyprzedzeniem przed datą egzekwowania.
Możliwe wartości plików cookie G_AUTH2_MIGRATION
:
enforced
Nie wczytuj moduługapi.auth2
.informational
Loguj używanie wycofanej funkcji w konsoli JS. Zapisz też w pamięci sesji, gdy ustawiono opcjonalną nazwę klucza:informational:key-name
.
Aby zminimalizować negatywny wpływ na użytkowników, zalecamy utworzenie pliku cookie lokalnie na etapie programowania i testowania, a następnie użycia go w środowiskach produkcyjnych.
Biblioteki i moduły
Moduł gapi.auth2
zarządza uwierzytelnianiem użytkowników podczas logowania i przepływem autoryzacji, który zastępuje ten wycofany moduł oraz jego obiekty i metody biblioteką usług tożsamości Google.
Dodaj usługę Identity Services 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ą polecenia gapi.load('auth2', function)
.
Biblioteka usług Google Identity zastępuje korzystanie z modułu gapi.auth2
.
Możesz nadal bezpiecznie korzystać z modułu gapi.client
w Bibliotece klienta interfejsu API Google dla języka JavaScript i korzystać z automatycznego wywoływania metod JS z dokumentu wykrywania, grupowania wielu wywołań interfejsu API i funkcji zarządzania CORS.
Pliki cookie
Autoryzacja użytkowników nie wymaga stosowania plików cookie.
Więcej informacji o tym, jak uwierzytelnianie użytkowników korzysta z plików cookie, znajdziesz w artykule o migracji z logowania przez Google, a o tym, jak Google używa plików cookie na potrzeby używania tych plików 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 to odrębne elementy: token tożsamości używany do identyfikowania użytkownika jest zwracany niezależnie od tokena dostępu używanego do autoryzacji.
Informacje o tych zmianach znajdziesz w przykładowych danych logowania.
Uwierzytelnienie bezpośrednie
Rozdziel uwierzytelnianie użytkowników i autoryzację przez usunięcie obsługi profilu użytkownika z procesów autoryzacji.
Usuń te materiały referencyjne klienta JavaScript dotyczące logowania przez Google:
Metody
GoogleUser.getBasicProfile()
GoogleUser.getId()
Przepływ kodu autoryzacji
Usługi tożsamości dzielą dane logowania w przeglądarce na tokeny tożsamości i tokeny dostępu. Ta zmiana nie dotyczy danych logowania uzyskanych za pomocą bezpośrednich połączeń z punktami końcowymi Google OAuth 2.0 z platformy backendu ani z bibliotek działających 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:
- Moduły obsługi wywołań zwrotnych w celu monitorowania stanu sesji użytkownika.
- Detektory zdarzeń i zmian stanu zalogowania na koncie Google użytkownika.
Odpowiadasz za zarządzanie stanem logowania i sesjami użytkownika w aplikacji internetowej.
Usuń te materiały referencyjne klienta JavaScript dotyczące logowania przez Google:
Obiekty:
gapi.auth2.SignInOptions
Metody:
GoogleAuth.attachClickHandler()
GoogleAuth.isSignedIn()
GoogleAuth.isSignedIn.get()
GoogleAuth.isSignedIn.listen()
GoogleAuth.signIn()
GoogleAuth.signOut()
GoogleAuth.currentUser.get()
GoogleAuth.currentUser.listen()
GoogleUser.isSignedIn()
Konfiguracja klienta
Zaktualizuj aplikację internetową, aby zainicjować klienta tokenu na potrzeby niejawnego lub autoryzacji kodu.
Usuń te materiały referencyjne klienta JavaScript dotyczące logowania 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 z tego przykładu.
Zastąp odwołania do klienta JavaScriptu 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_hint
–TokenClientConfig.login_hint
.gapi.auth2.GoogleUser.getHostedDomain()
–TokenClientConfig.hd
.
Przepływ kodu autoryzacji
Dodaj obiekt CodeClientConfig
i wywołanie initCodeClient()
, aby skonfigurować aplikację internetową zgodnie z przykładem z tego, jak inicjować klienta kodu.
W przypadku przejściowych sesji kodu autoryzacji:
Usuń Materiały referencyjne klienta JavaScript dotyczącego 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 zostaje zwrócony bezpośrednio do przeglądarki użytkownika z przepływem niejawnym lub do platformy backendu po zamianie kodu autoryzacji użytkownika na token dostępu i odświeżony token.
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 odwołania do klienta JavaScriptu 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ć funkcję requestAccessToken()
w celu zainicjowania wyskakującego przepływu UX w celu zażądania tokena dostępu lub uzyskania nowego tokena, gdy istniejący token wygaśnie.
Zaktualizuj bazę kodu, aby:
- Aktywuj przepływ tokenów OAuth 2.0 za pomocą polecenia
requestAccessToken()
. - Aby obsługiwać przyrostową autoryzację, używaj
requestAccessToken
iOverridableTokenClientConfig
do rozdzielania jednego żądania na wiele zakresów na kilka mniejszych żądań. - Poproś o nowy token, jeśli 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ą potrzebne, a nie ze wszystkich naraz. Jest to tzw. autoryzacja przyrostowa. Każde żądanie powinno zawierać jak najwięcej zakresów, a najlepiej pojedynczy. Więcej informacji na temat aktualizowania aplikacji w celu przyrostowej autoryzacji znajdziesz w tym artykule.
Po wygaśnięciu tokena dostępu moduł gapi.auth2
automatycznie otrzymuje nowy, ważny token dostępu do 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 tożsamości Google. Twoja aplikacja internetowa musi być zaktualizowana, aby wykrywać nieważny dostęp 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ć stronę 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 zareagować na wygasły lub unieważniony token dostępu, znajdziesz w sekcji dotyczącej obsługi tokenów poniżej.
Obsługa tokenów
Dodaj obsługę błędów, aby wykrywać nieudane wywołania interfejsu Google API w przypadku użycia nieważnego lub unieważnionego tokena dostępu, a także aby poprosić o nowy, ważny token dostępu.
Gdy używany jest wygasły lub unieważniony token dostępu, Google zwraca kod stanu HTTP 401 Unauthorized
i invalid_token
. Przykład znajdziesz w artykule Nieprawidłowa odpowiedź tokena.
Wygasłe tokeny
Tokeny dostępu są ważne tylko przez krótki czas 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ę.
To spowoduje unieważnienie istniejących tokenów dostępu i tokenów odświeżania. Unieważnienie platformie może zostać aktywowane za pomocą revoke()
lub konta Google.
Zastąp odwołania do klienta JavaScriptu 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 chce usunąć zgodę na udostępnianie danych aplikacji.
Prośba o zgodę użytkownika
Google wyświetla użytkownikowi okno z prośbą o zgodę na przetwarzanie danych, 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.
Zanim wygenerujesz token dostępu do swojej aplikacji, prośba o zgodę użytkownika i zarejestrowanie wyniku będzie wymagała aktywnej i aktywnej sesji Google. Jeśli istniejąca sesja użytkownika nie została jeszcze rozpoczęta, konieczne może być zalogowanie się na konto Google.
Logowanie użytkownika
Użytkownicy mogą być zalogowani na konto Google w 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ą przy pierwszym uruchomieniu aplikacji przez użytkownika. Dzięki temu uzyskasz te korzyści:
- Minimalizuje liczbę przypadków, w których użytkownik musi się zalogować. Prośba o token dostępu inicjuje proces logowania się na konto Google, jeśli aktywna sesja jeszcze nie istnieje.
- Jako wartości parametru
login_hint
w obiektachCodeClientConfig
lubTokenClientConfig
używaj bezpośrednio pola dane logowania tokena tokena JWTemail
. Jest to szczególnie przydatne, jeśli platforma nie obsługuje systemu zarządzania kontami użytkowników. - Wyszukiwanie i powiązanie konta Google z istniejącym lokalnym kontem użytkownika na platformie, co pozwala zminimalizować liczbę zduplikowanych kont.
- Po utworzeniu nowego konta lokalnego Twoje okna dialogowe i procedurę rejestracji można wyraźnie oddzielić od okien uwierzytelniania i przepływów uwierzytelniania użytkowników, zmniejszając liczbę wymaganych kroków i zwiększając współczynnik porzuceń.
Po zalogowaniu się, a przed wystawieniem tokena dostępu, użytkownicy muszą wyrazić zgodę na aplikację w żądanych zakresach.
Odpowiedź tokena i zgody
Po wyrażeniu zgody zwracany jest token dostępu wraz z listą zakresów zatwierdzonych lub odrzuconych przez użytkownika.
Dzięki szczegółowemu uprawnieniom użytkownicy mogą zatwierdzać lub odrzucać poszczególne zakresy. Gdy prosisz o dostęp do wielu zakresów, każdy zakres jest przyznawany lub odrzucany niezależnie od pozostałych. Na podstawie wyboru użytkownika aplikacja włącza funkcje zależne od poszczególnych zakresów.
Uwierzytelnienie bezpośrednie
Zastąp odwołania do klienta JavaScriptu 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ń Dokumentacja klienta JavaScript Logowania przez Google:
Metody:
GoogleUser.getAuthResponse()
Zaktualizuj aplikację internetową, podając wartości hasGrantedAllScopes()
i hasGrantedAnyScope()
, postępując zgodnie z tym przykładem uprawnień.
Przepływ kodu autoryzacji
Zaktualizuj lub dodaj do swojego backendu backendowy kod autoryzacji, postępując zgodnie z instrukcjami obsługi kodu autoryzacji.
Zaktualizuj platformę, aby wykonać czynności opisane w przewodniku po korzystaniu z modelu kodu, co pozwoli zweryfikować żądanie i uzyskać token dostępu oraz token odświeżania.
Zaktualizuj platformę, aby selektywnie włączać i wyłączać funkcje na podstawie poszczególnych zakresów zaakceptowanych przez użytkownika, postępując zgodnie z instrukcjami upoważnienia przyrostowego i sprawdzania 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 uruchomionej w przeglądarce w wyskakującym oknie dotyczącym zgody użytkownika.
Moduł gapi.auth2
jest automatycznie ładowany 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 uruchomiony 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 i przekierowuje użytkowników do Google na potrzeby zgody 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 pokazuje tylko bibliotekę JavaScript usługi Google Identity przy użyciu modelu tokena i wyskakującego okienka dotyczącego zgody użytkownika. Ma ona ilustrować 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 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 oczekiwania są używane do wymuszania kolejności wczytywania bibliotek oraz wykrywania i ponownych 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”, gdy brakuje tokena dostępu podczas pierwszego wczytywania strony lub 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 interfejsu 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 wymuszania kolejności wczytywania biblioteki. Wywołania GAPI są wykonywane w wywołaniu zwrotnym po zwróceniu prawidłowego tokena dostępu.
Użytkownicy powinni nacisnąć przycisk Pokaż kalendarz po pierwszym wczytaniu strony, a następnie, gdy chcą odświeżyć informacje o kalendarzu.
<!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 adresu URL, by zwrócić kod autoryzacji bezpośrednio do punktu końcowego tokena backendu, lub modułu obsługi wywołania JavaScriptu uruchomionego w przeglądarce użytkownika, który przekazuje odpowiedź na Twoją platformę. W obu przypadkach platforma backendu ukończy procedurę 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 przypadku aplikacji 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 serwera WWW 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 <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
Ten przykład pokazuje tylko bibliotekę JavaScript usługi Google Identity Service za pomocą modelu kodu autoryzacji wyskakującego okienka służącego do uzyskiwania zgody użytkownika i modułu wywołania zwrotnego służącego do odbierania od Google kodu autoryzacji. Służy on do zilustrowania minimalnej liczby kroków 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 wyskakujących okienek i przekierowań, które umożliwiają wysyłanie kodu autoryzacji poszczególnych użytkowników do punktu końcowego hostowanego przez Twoją platformę. Tryb UX przekierowania 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, która konsoliduje i zastępuje funkcje dostępne w wielu różnych bibliotekach i modułach:
- Klient JavaScript Logowania przez Google i
- Biblioteka klienta interfejsów API Google do JavaScriptu.
Działania, które należy podjąć 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. |
Biblioteka
Porównanie obiektu i metody między biblioteką Stary klienci JavaScriptu logowania Google a biblioteką Nowa usług tożsamości Google wraz z uwagami, które zawierają dodatkowe informacje oraz działania do wykonania podczas migracji.
Stara wersja | Nowi | Uwagi |
---|---|---|
Obiekt GoogleAuth i powiązane z nim metody: | ||
Funkcja 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ń go. | |
GoogleAuth.isSignedIn.get(). | Usuń | |
GoogleAuth.isSignedIn.listen(). | Usuń | |
Funkcja 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 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 tego użyj tokena tożsamości w artykule Migracja z logowania przez Google. | |
GoogleUser.getGrantedScopes() | hasGrantedAnyScope() | Zastąp stare nowym |
GoogleUser.getHostDomain() | Usuń | |
Funkcja GoogleUser.getId() | Usuń | |
GoogleUser.grantOfflineAccess() | Usuń go. | |
GoogleUser.grant() | Usuń | |
GoogleUser.hasGrantedScopes() | hasGrantedAnyScope() | Zastąp stare nowym |
GoogleUser.isSignedIn() | Usuń | |
GoogleUser.reloadAuthResponse() | requestAccessToken() | Usuń stare. Wywołaj nowy, aby wygasł lub unieważniono token dostępu. |
obiektu gapi.auth2 i powiązanych metod: | ||
Obiekt gapi.auth2.AuthorizeConfig | TokenClientConfig lub CodeClientConfig | Zastąp stare nowym |
Obiekt gapi.auth2.AuthorizeResponse | Usuń | |
Obiekt gapi.auth2.AuthResponse | Usuń | |
gapi.auth2.authorized(), | requestCode() lub requestAccessToken() | Zastąp stare nowym |
funkcja 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ń | |
obiektu gapi.signin2 i powiązanych metod: | ||
gapi.signin2.render() | Usuń. załadowanie elementu HTML DOM elementu g_id_signin lub wywołania JS do obiektu 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 interfejsów API Google dla JavaScriptu lub bezpośrednie wywołania punktów końcowych Google Auth 2.0 zwracają w jednej odpowiedzi token dostępu OAuth 2.0 oraz token identyfikatora OpenID Connect.
Przykładowa odpowiedź zawierająca zarówno tekst 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 usług Google Identity
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 do uwierzytelniania:
{
"clientId": "538344653255-758c5h5isc45vgk27d8h8deabovpg6to.apps.googleusercontent.com",
"credential": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImMxODkyZWI0OWQ3ZWY5YWRmOGIyZTE0YzA1Y2EwZDAzMjcxNGEyMzciLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJuYmYiOjE2MzkxNTcyNjQsImF1ZCI6IjUzODM0NDY1MzI1NS03NThjNWg1aXNjNDV2Z2syN2Q4aDhkZWFib3ZwZzZ0by5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbSIsInN1YiI6IjExNzcyNjQzMTY1MTk0MzY5ODYwMCIsIm5vbmNlIjoiZm9vYmFyIiwiaGQiOiJnb29nbGUuY29tIiwiZW1haWwiOiJkYWJyaWFuQGdvb2dsZS5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYXpwIjoiNTM4MzQ0NjUzMjU1LTc1OGM1aDVpc2M0NXZnazI3ZDhoOGRlYWJvdnBnNnRvLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwibmFtZSI6IkJyaWFuIERhdWdoZXJ0eSIsInBpY3R1cmUiOiJodHRwczovL2xoMy5nb29nbGV1c2VyY29udGVudC5jb20vYS0vQU9oMTRHZ3pwMk1zRkRmb21XTF91Q3pkWFFjc3lTN2RrcUxOcm5PdEtEM1VzUT1zOTYtYyIsImdpdmVuX25hbWUiOiJCcmlhbiIsImZhbWlseV9uYW1lIjoiRGF1Z2hlcnR5IiwiaWF0IjoxNjM5MTU3NTY0LCJleHAiOjE2MzkxNjExNjQsImp0aSI6IjRiOTVkYjAyZjU4NDczMmUxZGJkOTY2NWJiMWYzY2VhYzgyMmI0NjUifQ.Cr-AgMsLFeLurnqyGpw0hSomjOCU4S3cU669Hyi4VsbqnAV11zc_z73o6ahe9Nqc26kPVCNRGSqYrDZPfRyTnV6g1PIgc4Zvl-JBuy6O9HhClAK1HhMwh1FpgeYwXqrng1tifmuotuLQnZAiQJM73Gl-J_6s86Buo_1AIx5YAKCucYDUYYdXBIHLxrbALsA5W6pZCqqkMbqpTWteix-G5Q5T8LNsfqIu_uMBUGceqZWFJALhS9ieaDqoxhIqpx_89QAr1YlGu_UO6R6FYl0wDT-nzjyeF5tonSs3FHN0iNIiR3AMOHZu7KUwZaUdHg4eYkU-sQ01QNY_11keHROCRQ",
"select_by": "user"
}
Nieprawidłowa odpowiedź tokena
Przykładowa odpowiedź od Google przy próbie wysłania żądania do interfejsu API przy użyciu tokena, który wygasł, został unieważniony lub jest nieprawidłowy:
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"
}
}