OpenID Connect

Interfejsów API Google OAuth 2.0 można używać zarówno do uwierzytelniania, jak i autoryzacji. Ten dokument opisuje naszą implementację OAuth 2.0 do uwierzytelniania, która jest zgodna ze specyfikacją OpenID Connect i ma certyfikat OpenID. Dokumentacja dotycząca korzystania z protokołu OAuth 2.0 do uzyskiwania dostępu do interfejsów API Google ma zastosowanie również do tej usługi. Jeśli chcesz zapoznać się z tym protokołem w sposób interaktywny, skorzystaj z narzędzia Google OAuth 2.0 Playground. Aby uzyskać pomoc na stronie Stack Overflow, otaguj swoje pytania tagiem „google-oauth”.

Konfigurowanie OAuth 2.0

Zanim aplikacja będzie mogła używać systemu uwierzytelniania OAuth 2.0 Google do logowania użytkowników, musisz skonfigurować projekt w  Google API Console , aby uzyskać dane logowania OAuth 2.0, ustawić adres URI przekierowania i (opcjonalnie) dostosować informacje o markowaniu, które użytkownicy widzą na ekranie akceptacji. Możesz też użyć interfejsu API API Console , aby utworzyć konto usługi, włączyć rozliczenia, skonfigurować filtrowanie i wykonywać inne zadania. Więcej informacji znajdziesz w Google API ConsoleCentrum pomocy.

Uzyskiwanie danych logowania OAuth 2.0

Aby uwierzytelniać użytkowników i uzyskać dostęp do interfejsów API Google, musisz mieć dane uwierzytelniające OAuth 2.0, w tym identyfikator klienta i tajny klucz klienta.

Aby wyświetlić identyfikator klienta i klucz tajny klienta dla danego poświadczenia OAuth 2.0, kliknij następujący tekst: Wybierz poświadczenie . W oknie, które zostanie otwarte, wybierz projekt i żądane poświadczenia, a następnie kliknij opcję Wyświetl .

Lub wyświetl swój identyfikator klienta i API Console tajny klienta ze strony Poświadczenia w API Console :

  1. Go to the Credentials page.
  2. Kliknij nazwę swojego poświadczenia lub ikonę ołówka ( ). Twój identyfikator klienta i sekret znajdują się u góry strony.

Ustawianie identyfikatora URI przekierowania

Identyfikator URI przekierowania ustawiony w  API Console określa, dokąd Google wysyła odpowiedzi na żądania uwierzytelniania.

Aby utworzyć, wyświetlić lub edytować identyfikatory URI przekierowania dla danego poświadczenia OAuth 2.0, wykonaj następujące czynności:

  1. Go to the Credentials page.
  2. W sekcji identyfikatorów klientów OAuth 2.0 na stronie kliknij poświadczenie.
  3. Wyświetl lub edytuj identyfikatory URI przekierowania.

Jeśli na stronie Poświadczenia nie ma sekcji identyfikatorów klientów OAuth 2.0 , Twój projekt nie ma poświadczeń OAuth. Aby je utworzyć, kliknij Utwórz dane logowania .

Dostosowywanie ekranu zgody użytkownika

W ramach uwierzytelniania OAuth 2.0 użytkownicy widzą ekran zgody, na którym opisujemy informacje, które udostępniają, oraz obowiązujące warunki. Gdy użytkownik loguje się w aplikacji, może zostać poproszony o udostępnienie aplikacji dostępu do swojego adresu e-mail i podstawowych informacji o koncie. Dostęp do tych informacji uzyskujesz za pomocą parametru scope, który aplikacja podaje w żądaniu uwierzytelniania. Za pomocą zakresów możesz też prosić o dostęp do innych interfejsów API Google.

Na ekranie zgody użytkownika wyświetlane są też informacje o markach, takie jak nazwa produktu, logo i adres URL strony głównej. Masz kontrolę nad informacjami dotyczącymi marki w usłudze API Console.

Aby włączyć ekran akceptacji projektu:

  1. Otwórz Consent Screen page w Google API Console .
  2. If prompted, select a project, or create a new one.
  3. Wypełnij formularz i kliknij Zapisz .

Na poniższym ekranie zgody widać, co użytkownik zobaczy, gdy w żądaniu występują zakresy OAuth 2.0 i Dysk Google. (Ten ogólny dialog został wygenerowany za pomocą Google OAuth 2.0 Playground, więc nie zawiera informacji o brandingu, które są ustawiane w  API Console).

Zrzut ekranu strony ze zgodą

Uzyskiwanie dostępu do usługi

Google i firmy zewnętrzne udostępniają biblioteki, których możesz używać do obsługi wielu szczegółów implementacji uwierzytelniania użytkowników i uzyskiwania dostępu do interfejsów API Google. Przykłady to usługi Google Identity Services i biblioteki klienta Google, które są dostępne na różnych platformach.

Jeśli zdecydujesz się nie używać biblioteki, postępuj zgodnie z instrukcjami podanymi w dalszej części tego dokumentu, w którym opisano przepływy żądań HTTP stanowiące podstawę dostępnych bibliotek.

Uwierzytelnianie użytkownika

Uwierzytelnianie użytkownika polega na uzyskaniu tokena identyfikacyjnego i jego sprawdzeniu. Tokeny identyfikacyjne to standardowa funkcja OpenID Connect, która służy do udostępniania informacji o tożsamości w Internecie.

Najczęściej stosowane metody uwierzytelniania użytkownika i uzyskiwania tokena tożsamości to „przepływ po stronie serwera” i „przepływ niejawny”. Proces serwera umożliwia serwerowi zaplecza aplikacji weryfikowanie tożsamości osoby korzystającej z przeglądarki lub urządzenia mobilnego. Procedura ukryta jest używana, gdy aplikacja po stronie klienta (zwykle aplikacja w JavaScript działająca w przeglądarce) musi uzyskać dostęp do interfejsów API bezpośrednio zamiast przez serwer zaplecza.

Ten dokument zawiera opis przepływu danych na serwerze służącego do uwierzytelniania użytkownika. Proces niejawny jest znacznie bardziej skomplikowany ze względu na zagrożenia dla bezpieczeństwa związane z obsługą i używaniem tokenów po stronie klienta. Jeśli chcesz wdrożyć przepływ niejawny, zdecydowanie zalecamy korzystanie z usług Google Identity.

Proces na serwerze

Upewnij się, że skonfigurujesz aplikację w  API Console, aby umożliwić jej korzystanie z tych protokołów i uwierzytelnianie użytkowników. Gdy użytkownik spróbuje zalogować się w Google, musisz:

  1. Tworzenie tokena stanu zapobiegającego fałszowaniu
  2. Wysyłanie żądania uwierzytelniania do Google
  3. Potwierdź token stanu zapobiegania fałszerstwu
  4. Wymiana code na token dostępu i token identyfikacyjny
  5. Pobieranie informacji o użytkowniku z tokena identyfikatora
  6. Uwierzytelnianie użytkownika

1. Tworzenie tokena stanu zapobiegającego fałszowaniu

Musisz chronić bezpieczeństwo swoich użytkowników, zapobiegając atakom polegającym na fałszowaniu żądań. Pierwszym krokiem jest utworzenie unikalnego tokena sesji, który przechowuje stan między aplikacją a klientem użytkownika. Następnie porównujesz ten unikalny token sesji z odpowiedzią uwierzytelniania zwróconą przez usługę logowania OAuth Google, aby sprawdzić, czy żądanie wysłał użytkownik, a nie złośliwy atakujący. Takie tokeny są często nazywane tokenami do fałszowania żądań między witrynami (CSRF).

Dobrym wyborem tokena stanowego jest ciąg znaków o długości około 30 znaków utworzony za pomocą wysokiej jakości generatora liczb losowych. Kolejnym jest hasz wygenerowany przez podpisanie niektórych zmiennych stanu sesji za pomocą klucza, który jest utrzymywany w tajemnicy na serwerze.

Poniższy kod pokazuje, jak wygenerować unikalne tokeny sesji.

PHP

Aby użyć tego przykładu, musisz pobrać bibliotekę klienta interfejsów API Google dla języka PHP.

// Create a state token to prevent request forgery.
// Store it in the session for later validation.
$state = bin2hex(random_bytes(128/8));
$app['session']->set('state', $state);
// Set the client ID, token state, and application name in the HTML while
// serving it.
return $app['twig']->render('index.html', array(
    'CLIENT_ID' => CLIENT_ID,
    'STATE' => $state,
    'APPLICATION_NAME' => APPLICATION_NAME
));

Java

Aby użyć tego przykładu, musisz pobrać bibliotekę klienta interfejsów API Google dla języka Java.

// Create a state token to prevent request forgery.
// Store it in the session for later validation.
String state = new BigInteger(130, new SecureRandom()).toString(32);
request.session().attribute("state", state);
// Read index.html into memory, and set the client ID,
// token state, and application name in the HTML before serving it.
return new Scanner(new File("index.html"), "UTF-8")
    .useDelimiter("\\A").next()
    .replaceAll("[{]{2}\\s*CLIENT_ID\\s*[}]{2}", CLIENT_ID)
    .replaceAll("[{]{2}\\s*STATE\\s*[}]{2}", state)
    .replaceAll("[{]{2}\\s*APPLICATION_NAME\\s*[}]{2}",
    APPLICATION_NAME);

Python

Aby użyć tego przykładu, musisz pobrać bibliotekę klienta interfejsów API Google do języka Python.

# Create a state token to prevent request forgery.
# Store it in the session for later validation.
state = hashlib.sha256(os.urandom(1024)).hexdigest()
session['state'] = state
# Set the client ID, token state, and application name in the HTML while
# serving it.
response = make_response(
    render_template('index.html',
                    CLIENT_ID=CLIENT_ID,
                    STATE=state,
                    APPLICATION_NAME=APPLICATION_NAME))

2. Wysyłanie żądania uwierzytelniania do Google

Kolejnym krokiem jest utworzenie żądania HTTPS GET z odpowiednimi parametrami identyfikatora URI. Pamiętaj, że w każdym kroku tego procesu należy używać protokołu HTTPS, a nie HTTP. Identyfikator URI podstawowy należy pobrać z dokumentu Discovery, używając wartości metadanych authorization_endpoint. W dalszej części tekstu zakładamy, że podstawowy identyfikator URI to https://accounts.google.com/o/oauth2/v2/auth.

W przypadku podstawowego żądania podaj te parametry:

  • client_id, które można uzyskać z  API Console Credentials page .
  • response_type, który w przypadku podstawowego przepływu kodu autoryzacji powinien być code. (więcej informacji znajdziesz w artykule response_type).
  • scope, który w podstawowym żądaniu powinien być openid email. (więcej informacji znajdziesz w artykule scope).
  • redirect_uri powinien być punktem końcowym HTTP na serwerze, który otrzyma odpowiedź od Google. Wartość musi dokładnie pasować do jednego z autoryzowanych identyfikatorów URI przekierowania dla klienta OAuth 2.0 skonfigurowanego w API Console Credentials page. Jeśli ta wartość nie pasuje do autoryzowanego identyfikatora URI, żądanie zakończy się niepowodzeniem z powodu błędu redirect_uri_mismatch.
  • Wartość parametru state powinna zawierać wartość unikalnego tokena sesji zapobiegającej fałszowaniu, a także inne informacje potrzebne do przywrócenia kontekstu, gdy użytkownik wróci do aplikacji, np. początkowy adres URL. (więcej informacji znajdziesz w artykule state).
  • nonce to losowa wartość wygenerowana przez aplikację, która umożliwia ochronę przed odtwarzaniem w przypadku jej obecności.
  • login_hint może być adresem e-mail użytkownika lub ciągiem sub, który jest równoważny identyfikatorowi Google użytkownika. Jeśli nie podasz wartości login_hint i użytkownik jest obecnie zalogowany, ekran zgody będzie zawierać prośbę o zatwierdzenie udostępnienia Twojej aplikacji adresu e-mail użytkownika. (Więcej informacji znajdziesz w sekcji login_hint).
  • Użyj parametru hd, aby zoptymalizować proces OpenID Connect dla użytkowników z danej domeny powiązanej z organizacją Google Workspace lub Cloud (więcej informacji znajdziesz w artykule hd).

Oto przykład pełnego identyfikatora URI uwierzytelniania OpenID Connect z przecinkami i przerwami między wierszami w celu ułatwienia odczytania:

https://accounts.google.com/o/oauth2/v2/auth?
 response_type=code&
 client_id=424911365001.apps.googleusercontent.com&
 scope=openid%20email&
 redirect_uri=https%3A//oauth2.example.com/code&
 state=security_token%3D138r5719ru3e1%26url%3Dhttps%3A%2F%2Foauth2-login-demo.example.com%2FmyHome&
 login_hint=jsmith@example.com&
 nonce=0394852-3190485-2490358&
 hd=example.com

Użytkownicy muszą wyrazić zgodę, jeśli aplikacja prosi o nowe informacje o nich lub o dostęp do konta, którego nie zatwierdzili wcześniej.

3. Potwierdź token stanu zapobiegania fałszerstwu

Odpowiedź jest wysyłana do redirect_uri określonego w żądaniu. Wszystkie odpowiedzi są zwracane w formie ciągu zapytania, jak pokazano poniżej:

https://oauth2.example.com/code?state=security_token%3D138r5719ru3e1%26url%3Dhttps%3A%2F%2Foa2cb.example.com%2FmyHome&code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&scope=openid%20email%20https://www.googleapis.com/auth/userinfo.email

Na serwerze musisz potwierdzić, że state otrzymany od Google jest zgodny z tokenem sesji utworzonym w kroku 1. Ta weryfikacja w obie strony pomaga zapewnić, że żądanie wysyła użytkownik, a nie złośliwy skrypt.

Ten kod pokazuje potwierdzenie tokenów sesji utworzonych w kroku 1:

PHP

Aby użyć tego przykładu, musisz pobrać bibliotekę klienta interfejsów API Google dla języka PHP.

// Ensure that there is no request forgery going on, and that the user
// sending us this connect request is the user that was supposed to.
if ($request->get('state') != ($app['session']->get('state'))) {
  return new Response('Invalid state parameter', 401);
}

Java

Aby użyć tego przykładu, musisz pobrać bibliotekę klienta interfejsów API Google dla języka Java.

// Ensure that there is no request forgery going on, and that the user
// sending us this connect request is the user that was supposed to.
if (!request.queryParams("state").equals(
    request.session().attribute("state"))) {
  response.status(401);
  return GSON.toJson("Invalid state parameter.");
}

Python

Aby użyć tego przykładu, musisz pobrać bibliotekę klienta interfejsów API Google do języka Python.

# Ensure that the request is not a forgery and that the user sending
# this connect request is the expected user.
if request.args.get('state', '') != session['state']:
  response = make_response(json.dumps('Invalid state parameter.'), 401)
  response.headers['Content-Type'] = 'application/json'
  return response

4. Wymiana code na token dostępu i token identyfikatora

Odpowiedź zawiera parametr code, czyli jednorazowy kod autoryzacji, który Twój serwer może zamienić na token dostępu i token identyfikacyjny. Twój serwer wykonuje tę wymianę, wysyłając żądanie HTTPS POST. Żądanie POST jest wysyłane do punktu końcowego tokenu, który należy pobrać z dokumentu Discovery, używając wartości metadanych token_endpoint. W dalszej części artykułu przyjmujemy, że punkt końcowy to https://oauth2.googleapis.com/token. Żądanie musi zawierać te parametry w swoim POST:

Pola
code Kod autoryzacji zwracany przez wstępne żądanie.
client_id Identyfikator klienta uzyskany z  API Console Credentials pagezgodnie z opisem w artykule Uzyskiwanie danych logowania OAuth 2.0.
client_secret Klucz klienta uzyskany z  API Console Credentials pagezgodnie z opisem w artykule Uzyskiwanie danych logowania OAuth 2.0.
redirect_uri Autoryzowany identyfikator URI przekierowania dla danego client_id, który został określony w  API Console: Credentials page, zgodnie z opisem w sekcji Konfigurowanie identyfikatora URI przekierowania.
grant_type To pole musi zawierać wartość authorization_code, zdefiniowaną w specyfikacji OAuth 2.0.

Rzeczywiste żądanie może wyglądać tak:

POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded

code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
client_id=your-client-id&
client_secret=your-client-secret&
redirect_uri=https%3A//oauth2.example.com/code&
grant_type=authorization_code

Odpowiedź na to żądanie zawiera te pola w tablicy JSON:

Pola
access_token token, który można wysłać do interfejsu Google API;
expires_in Pozostały czas ważności tokena dostępu w sekundach.
id_token JWT zawierający informacje o tożsamości użytkownika, który jest podpisany cyfrowo przez Google.
scope Zakresy dostępu przyznawane przez access_token wyrażone jako lista rozdzielanych spacjami ciągów znaków rozróżniających wielkość liter.
token_type Wskazuje typ zwróconego tokena. Obecnie to pole ma zawsze wartość Bearer.
refresh_token (opcjonalnie)

To pole jest widoczne tylko wtedy, gdy parametr access_type ma wartość offline w żądaniu uwierzytelniania. Więcej informacji znajdziesz w artykule Tokeny odświeżania.

5. Pobieranie informacji o użytkowniku z tokena identyfikatora

Token tożsamości to JWT, czyli obiekt JSON podpisany kryptograficznie i zakodowany w formacie Base64. Zazwyczaj przed użyciem tokena ID musisz go zweryfikować, ale ponieważ komunikujesz się bezpośrednio z Google przez kanał HTTPS bez pośredników i używasz tajnego klucza klienta do uwierzytelnienia się w Google, możesz mieć pewność, że otrzymany token pochodzi od Google i jest prawidłowy. Jeśli serwer przekazuje token identyfikacyjny innym komponentom aplikacji, bardzo ważne jest, aby te komponenty zweryfikowały token przed jego użyciem.

Ponieważ większość bibliotek interfejsu API łączy weryfikację z dekodowaniem wartości zakodowanych w formacie base64url i analizą zawartości JSON, prawdopodobnie i tak zweryfikujesz token, gdy uzyskasz dostęp do roszczeń w tokenie identyfikacyjnym.

ładunek tokena identyfikatora;

Token tożsamości to obiekt JSON zawierający zbiór par nazwa/wartość. Oto przykład sformatowanego tekstu w celu ułatwienia jego czytania:

{
  "iss": "https://accounts.google.com",
  "azp": "1234987819200.apps.googleusercontent.com",
  "aud": "1234987819200.apps.googleusercontent.com",
  "sub": "10769150350006150715113082367",
  "at_hash": "HK6E_P6Dh8Y93mRNtsDB1Q",
  "hd": "example.com",
  "email": "jsmith@example.com",
  "email_verified": "true",
  "iat": 1353601026,
  "exp": 1353604926,
  "nonce": "0394852-3190485-2490358"
}

Tokeny tożsamości Google mogą zawierać te pola (nazywane deklaracjami):

Roszczenie Udostępniony Opis
aud zawsze Odbiorcy, dla których jest przeznaczony dany token tożsamości. Musi to być jeden z identyfikatorów klienta OAuth 2.0 Twojej aplikacji.
exp zawsze Czas, po upływie którego token identyfikatora nie może być akceptowany. Podany jako czas uniksowy (całkowita liczba sekund).
iat zawsze Czas wystawienia tokena tożsamości. Podany jako czas uniksowy (całkowita liczba sekund).
iss zawsze Identyfikator wystawcy odpowiedzi. W przypadku tokenów tożsamości Google zawsze jest to https://accounts.google.com lub accounts.google.com.
sub zawsze Identyfikator użytkownika, niepowtarzalny wśród wszystkich kont Google i nieużywany ponownie. Konto Google może mieć w różnych momentach wiele powiązanych adresów e-mail, ale wartość sub nie zmienia się nigdy. Użyj właściwości sub w swojej aplikacji jako unikalnego klucza identyfikatora użytkownika. Maksymalna długość to 255 znaków ASCII z uwzględnieniem wielkości liter.
at_hash Hasz tokena dostępu. Potwierdza, że token dostępu jest powiązany z tokenem tożsamości. Jeśli w ramach procesu na serwerze token ID jest wydawany z wartością access_token, ten identyfikator jest zawsze uwzględniany. Tego oświadczenia można używać jako alternatywnego mechanizmu ochrony przed atakami polegającymi na fałszowaniu żądań między witrynami, ale jeśli wykonasz Krok 1Krok 3, nie musisz weryfikować tokena dostępu.
azp client_id autoryzowanej aplikacji prezentującej token. Ta deklaracja jest potrzebna tylko wtedy, gdy strona żądająca tokena tożsamości różni się od jego odbiorcy. W Google może tak być w przypadku aplikacji hybrydowych, gdy aplikacja internetowa i aplikacja na Androida mają inny identyfikator OAuth 2.0, ale są związane z tym samym projektem interfejsów API Google.client_id
email Adres e-mail użytkownika. Podawana tylko wtedy, gdy w żądaniu uwzględniono zakres email. Wartość tego oświadczenia może nie być unikalna dla tego konta i może się zmienić w czasie, dlatego nie należy jej używać jako głównego identyfikatora do łączenia z rekordem użytkownika. Nie możesz też używać domeny w zasadzie email do identyfikowania użytkowników Google Workspace ani organizacji Cloud. Zamiast tego użyj zasady hd.
email_verified Wartość „prawda”, jeśli adres e-mail użytkownika został zweryfikowany. W przeciwnym razie „fałsz”.
family_name Nazwisko(-a) użytkownika. Ten atrybut może być podany, gdy występuje roszczenie name.
given_name Imię lub imiona użytkownika. Ten atrybut może być podany, gdy występuje roszczenie name.
hd Domena powiązana z organizacją Google Workspace lub Cloud użytkownika. Podawana tylko wtedy, gdy użytkownik należy do organizacji Google Cloud. Musisz zaznaczyć to roszczenie, gdy ograniczasz dostęp do zasobu tylko do użytkowników z określonych domen. Brak tego oświadczenia oznacza, że konto nie należy do domeny hostowanej przez Google.
locale Lokalizacja użytkownika reprezentowana przez tag języka BCP 47. Ten atrybut może być podany, gdy występuje roszczenie name.
name Pełne imię i nazwisko użytkownika w możliwej do wyświetlenia postaci. Może być podany w przypadku:
  • Zakres żądania zawierał ciąg znaków „profile”.
  • Token identyfikacji jest zwracany z odświeżenia tokenu.

Jeśli występują oświadczenia name, możesz ich użyć do zaktualizowania rekordów użytkowników aplikacji. Pamiętaj, że nie zawsze jest ono widoczne.

nonce Wartość nonce dostarczona przez aplikację w żądaniu uwierzytelnienia. Zadbaj o to, aby była wyświetlana tylko raz, co zapewni ochronę przed atakami typu replay.
picture Adres URL zdjęcia profilowego użytkownika. Może być podany w przypadku:
  • Zakres żądania zawierał ciąg znaków „profile”.
  • Token identyfikacji jest zwracany z odświeżenia tokenu.

Jeśli występują oświadczenia picture, możesz ich użyć do zaktualizowania rekordów użytkowników aplikacji. Pamiętaj, że nie zawsze jest ono widoczne.

profile Adres URL strony profilu użytkownika. Może być podany w przypadku:
  • Zakres żądania zawierał ciąg znaków „profile”.
  • Token identyfikacji jest zwracany z odświeżenia tokenu.

Jeśli występują oświadczenia profile, możesz ich użyć do zaktualizowania rekordów użytkowników aplikacji. Pamiętaj, że nie zawsze jest ono widoczne.

6. Uwierzytelnienie użytkownika

Po uzyskaniu informacji o użytkowniku z tokena ID należy przesłać zapytanie do bazy danych użytkowników aplikacji. Jeśli użytkownik jest już obecny w Twojej bazie danych, uruchom sesję aplikacji dla tego użytkownika, jeśli odpowiedź interfejsu Google API spełnia wszystkie wymagania logowania.

Jeśli użytkownik nie istnieje w Twojej bazie danych, przekieruj go do procesu rejestracji nowych użytkowników. Możesz automatycznie zarejestrować użytkownika na podstawie informacji otrzymanych z Google lub przynajmniej wstępnie wypełnić wiele pól wymaganych w formularzu rejestracyjnym. Oprócz informacji w tokenie ID możesz uzyskać dodatkowe informacje o profilu użytkownika na naszych punktach końcowych profilu użytkownika.

Zaawansowane tematy

W następnych sekcjach znajdziesz bardziej szczegółowy opis interfejsu Google OAuth 2.0. Te informacje są przeznaczone dla deweloperów, którzy mają zaawansowane wymagania dotyczące uwierzytelniania i autoryzacji.

Dostęp do innych interfejsów API Google

Jedną z zalet korzystania z OAuth 2.0 do uwierzytelniania jest to, że aplikacja może uzyskać w imieniu użytkownika uprawnienia do korzystania z innych interfejsów API Google (takich jak YouTube, Dysk Google, Kalendarz czy Kontakty) w tym samym czasie, gdy uwierzytelnia użytkownika. Aby to zrobić, dodaj inne wymagane zakresy w żądaniu uwierzytelniania wysyłanym do Google. Aby na przykład dodać do żądania uwierzytelniania grupę wiekową użytkownika, podaj parametr zakresu openid email https://www.googleapis.com/auth/profile.agerange.read. Użytkownik zostaje poproszony o wyrażenie zgody na odpowiednim ekranie zgody. Token dostępu, który otrzymasz od Google, umożliwia dostęp do wszystkich interfejsów API związanych z zakresami dostępu, o które prosisz i które są przyznawane.

Tokeny odświeżania

W prośbie o dostęp do interfejsu API możesz poprosić o zwrócenie tokena odświeżania podczas codewymiany. Token odświeżania zapewnia aplikacji ciągły dostęp do interfejsów API Google, gdy użytkownik nie jest w niej obecny. Aby poprosić o token odświeżania, ustaw parametr access_type na offlineżądaniu uwierzytelnienia.

Uwagi:

  • Pamiętaj, aby bezpiecznie i trwało przechowywać token odświeżania, ponieważ można go uzyskać tylko podczas pierwszego wykonania procesu wymiany kodu.
  • Liczba wydawanych tokenów odświeżania jest ograniczona: jeden limit na kombinację klient/użytkownik oraz inny na użytkownika we wszystkich klientach. Jeśli aplikacja żąda zbyt wielu tokenów odświeżania, może przekroczyć te limity, co spowoduje, że starsze tokeny odświeżania przestaną działać.

Więcej informacji znajdziesz w artykule Odświeżanie tokena dostępu (dostęp offline).

Aby poprosić użytkownika o ponowne autoryzowanie aplikacji, w żądaniu uwierzytelniania ustaw parametr prompt na consent. Gdy włączysz opcję prompt=consent, ekran zgody będzie wyświetlany za każdym razem, gdy aplikacja będzie prosić o autoryzację zakresów dostępu, nawet jeśli wszystkie zakresy zostały wcześniej przyznane Twojemu projektowi interfejsów API Google. Z tego powodu uwzględniaj element prompt=consent tylko wtedy, gdy jest to konieczne.

Więcej informacji o parametrze prompt znajdziesz w tabeli Parametry URI uwierzytelniania (prompt).

Parametry identyfikatora URI uwierzytelniania

W tabeli poniżej znajdziesz bardziej szczegółowe opisy parametrów akceptowanych przez interfejs API uwierzytelniania OAuth 2.0 Google.

Parametr Wymagane Opis
client_id (Wymagane) ciąg znaków identyfikatora klienta uzyskany z  API Console Credentials pagezgodnie z opisem w artykule Uzyskiwanie danych logowania OAuth 2.0.
nonce (Wymagane) Losowa wartość wygenerowana przez aplikację, która umożliwia ochronę przed ponownym odtwarzaniem.
response_type (Wymagane) Jeśli wartość to code, uruchamia podstawowy proces kodu autoryzacji, który wymaga wysłania POST do punktu końcowego tokena w celu uzyskania tokenów. Jeśli wartość to token id_token lub id_token token, uruchamia implikowany proces, wymagający użycia JavaScriptu w identyfikatorze URI przekierowania, aby pobrać tokeny z identyfikatora URI #fragment.
redirect_uri (Wymagane) Określa, gdzie jest wysyłana odpowiedź. Wartość tego parametru musi dokładnie odpowiadać jednej z autoryzowanych wartości przekierowania ustawionych w  API Console Credentials page (w tym schemat HTTP lub HTTPS, wielkość liter i zakończenie „/”, jeśli występuje).
scope (Wymagane)

Parametr zakresu musi zaczynać się od wartości openid, a potem zawierać wartość profile, email lub obie te wartości.

Jeśli występuje wartość zakresu profile, token identyfikatora może (ale nie musi) zawierać domyślnych profile roszczeń użytkownika.

Jeśli występuje wartość zakresu email, token ID zawiera oświadczenia emailemail_verified.

Oprócz tych zakresów OpenID argument zakresu może zawierać też inne wartości zakresu. Wszystkie wartości zakresu muszą być rozdzielone spacjami. Jeśli na przykład chcesz uzyskać dostęp do Dysku Google użytkownika na poziomie pliku, parametr zakresu może wynosić openid profile email https://www.googleapis.com/auth/drive.file.

Informacje o dostępnych zakresach znajdziesz w Zakresy OAuth 2.0 dla interfejsów API Google lub w dokumentacji interfejsu API Google, którego chcesz użyć.

state (opcjonalne, ale zdecydowanie zalecane)

Nieprzejrzysty ciąg znaków, który jest przekazywany w obie strony w ramach protokołu, czyli zwracany jako parametr URI w schemacie podstawowym i w identyfikatorze URI #fragmentw schemacie domyślnym.

state może być przydatna do korelacji żądań i odpowiedzi. Wartość redirect_uri można odgadnąć, dlatego użycie wartości state może zwiększyć pewność, że połączenie przychodzące jest wynikiem żądania uwierzytelniania zainicjowanego przez Twoją aplikację. Jeśli w tej zmiennej state wygenerujesz losowy ciąg znaków lub zakodujesz hasz niektórych stanów klienta (np. pliku cookie), możesz zweryfikować odpowiedź, aby dodatkowo upewnić się, że żądanie i odpowiedź pochodzą z tego samego przeglądarki. Zapewnia to ochronę przed atakami takimi jak fałszowanie żądań między witrynami.

access_type (Opcjonalnie) Dozwolone wartości to offlineonline. Efekt jest udokumentowany w Dostępie offline. Jeśli wysłano żądanie tokena dostępu, klient nie otrzyma tokena odświeżania, chyba że zostanie podana wartość offline.
display (Opcjonalnie) Wartość ciągu ASCII określająca sposób wyświetlania stron uwierzytelniania i zgód w interfejsie użytkownika przez serwer autoryzacji. Na serwerach Google są określane i akceptowane te wartości: page, popup, touchwap, ale nie mają one wpływu na działanie usługi.
hd (Opcjonalnie)

Uprość proces logowania na kontach należących do organizacji Google Cloud. Uwzględniając domenę organizacji Google Cloud (np. mycollege.edu), możesz wskazać, że interfejs wyboru konta powinien być zoptymalizowany pod kątem kont w tej domenie. Aby zoptymalizować działanie dla kont organizacji Google Cloud, zamiast tylko jednej domeny organizacji Google Cloud, ustaw wartość gwiazdki (*): hd=*.

Nie polegaj na tej optymalizacji interfejsu, aby kontrolować, kto może uzyskać dostęp do aplikacji, ponieważ żądania po stronie klienta można modyfikować. Pamiętaj, aby potwierdzić, że zwrócony token identyfikacyjny ma wartość atrybutu hd, która jest zgodna z oczekiwaną (np. mycolledge.edu). W odróżnieniu od parametru żądania atrybut hd tokena identyfikacyjnego jest zawarty w tokenie zabezpieczeń Google, więc można mu ufać.

include_granted_scopes (Opcjonalnie) Jeśli ten parametr ma wartość true i żądanie autoryzacji zostanie zaakceptowane, autoryzacja będzie obejmować wszystkie wcześniejsze autoryzacje udzielone tej kombinacji użytkownik/aplikacja w przypadku innych zakresów. Więcej informacji znajdziesz w sekcji Dodatkowa autoryzacja.

Pamiętaj, że w przypadku procesu autoryzacji w aplikacji zainstalowanej na urządzeniu nie możesz korzystać z autoryzacji stopniowej.

login_hint (Opcjonalnie) Gdy aplikacja wie, którego użytkownika próbuje uwierzytelnić, może podać ten parametr jako podpowiedź dla serwera uwierzytelniania. Przekazanie tego podpowiedzi powoduje pominięcie selektora kont i wypełnienie pola adresu e-mail w formularzu logowania lub wybranie odpowiedniej sesji (jeśli użytkownik korzysta z wielokrotnego logowania). Dzięki temu można uniknąć problemów, które mogą wystąpić, jeśli aplikacja zaloguje się na niewłaściwe konto użytkownika. Wartością może być adres e-mail lub ciąg znaków sub, który jest równoważny z identyfikatorem Google użytkownika.
prompt (Opcjonalnie) Lista wartości ciągu znaków oddzielonych spacjami, która określa, czy serwer uwierzytelniania prosi użytkownika o ponowne uwierzytelnienie i zgodę. Możliwe wartości:
  • none

    Serwer autoryzacji nie wyświetla żadnych ekranów uwierzytelniania ani ekranów zgody użytkownika. Zwraca on błąd, jeśli użytkownik nie został jeszcze uwierzytelniony i nie ma wstępnie skonfigurowanej zgody na żądane zakresy. Możesz użyć none, aby sprawdzić, czy uwierzytelnianie lub zgoda są już dostępne.

  • consent

    Serwer autoryzacji prosi użytkownika o zgodę, zanim zwróci informacje do klienta.

  • select_account

    Serwer autoryzacji prosi użytkownika o wybranie konta użytkownika. Dzięki temu użytkownik, który ma wiele kont na serwerze autoryzacji, może wybrać jedno z nich, na którym może mieć bieżącą sesję.

Jeśli nie podasz żadnej wartości, a użytkownik nie wyraził wcześniej zgody na dostęp, wyświetli się ekran zgody.

Weryfikowanie tokena tożsamości

Musisz zweryfikować wszystkie tokeny identyfikacyjne na serwerze, chyba że wiesz, że pochodzą one bezpośrednio z Google. Na przykład serwer musi potwierdzić autentyczność tokenów identyfikacyjnych otrzymanych z aplikacji klienta.

Oto typowe sytuacje, w których możesz wysyłać na serwer tokeny identyfikacyjne:

  • Wysyłanie tokenów identyfikacyjnych z żądaniami, które wymagają uwierzytelnienia. Identyfikatory ID podają, który użytkownik wysłał żądanie i dla którego klienta został przyznany ten identyfikator.

Tokeny identyfikacyjne są poufne i w przypadku przechwycenia mogą zostać wykorzystane w niewłaściwy sposób. Musisz zadbać o to, aby te tokeny były przetwarzane w sposób bezpieczny, przesyłając je tylko przez HTTPS i tylko za pomocą danych POST lub w nagłówkach żądań. Jeśli przechowujesz tokeny identyfikacyjne na serwerze, musisz je też przechowywać w bezpieczny sposób.

Jednym z elementów, który czyni je przydatnymi, jest to, że możesz je przekazywać różnym komponentom aplikacji. Mogą one używać tokenu ID jako prostego mechanizmu uwierzytelniania, który uwierzytelnia aplikację i użytkownika. Zanim jednak użyjesz informacji z tokenu ID lub zaufasz mu jako potwierdzeniu uwierzytelnienia użytkownika, musisz go zweryfikować.

Aby zweryfikować token identyfikacyjny, wykonaj kilka czynności:

  1. Sprawdź, czy token identyfikatora jest prawidłowo podpisany przez wystawcę. Tokeny wydawane przez Google są podpisywane za pomocą jednego z certyfikatów znalezionych w identyfikatorze URI określonym w wartości metadanych jwks_uri w dokumencie Discovery.
  2. Sprawdź, czy wartość roszczenia iss w tokenie ID jest równa https://accounts.google.com lub accounts.google.com.
  3. Sprawdź, czy wartość atrybutu aud w tokenie identyfikacyjnym jest równa identyfikatorowi klienta aplikacji.
  4. Sprawdź, czy nie minął czas ważności (założenie exp) tokena identyfikacyjnego.
  5. Jeśli w żądaniu podano wartość parametru hd, sprawdź, czy token ID zawiera roszczenie hd, które pasuje do domeny akceptowanej przez organizację Google Cloud.

Kroki 2–5 dotyczą tylko porównywania ciągów znaków i danych, które są dość proste, dlatego nie będziemy ich tutaj szczegółowo omawiać.

Pierwszy krok jest bardziej złożony i polega na sprawdzeniu podpisu kryptograficznego. Do debugowania możesz użyć punktu końcowego tokeninfo Google, aby porównać przetwarzanie lokalne na serwerze lub urządzeniu z przetwarzaniem w chmurze. Załóżmy, że wartość Twojego tokena to: XYZ123. Następnie odwołuj się do identyfikatora URI. https://oauth2.googleapis.com/tokeninfo?id_token=XYZ123 Jeśli podpis tokena jest prawidłowy, odpowiedź będzie zawierać ładunek JWT w postaci zakodowanego obiektu JSON.

Punkt końcowy tokeninfo jest przydatny do debugowania, ale w celu wdrożenia wybierz opcję pobierania kluczy publicznych Google z punktu końcowego kluczy i przeprowadź weryfikację lokalnie. Identyfikatory URI kluczy należy pobrać z dokumentu Discovery, używając wartości metadanych jwks_uri. Żądania wysyłane do punktu końcowego debugowania mogą być ograniczane lub w inny sposób podlegać okresowym błędom.

Google zmienia klucze publiczne tylko sporadycznie, dlatego możesz je przechowywać w pamięci podręcznej za pomocą dyrektyw pamięci podręcznej w odpowiedzi HTTP. W większości przypadków weryfikacja lokalna jest znacznie wydajniejsza niż korzystanie z punktu końcowego tokeninfo. Ta weryfikacja wymaga pobrania i przeanalizowania certyfikatów oraz wykonania odpowiednich wywołań kryptograficznych w celu sprawdzenia podpisu. Na szczęście istnieją dobrze zdebugowane biblioteki dostępne w wielu językach, które umożliwiają realizację tego zadania (patrz jwt.io).

Pobieranie informacji z profilu użytkownika

Aby uzyskać dodatkowe informacje o profilu użytkownika, możesz użyć tokena dostępu (który aplikacja otrzymuje podczas przepływu uwierzytelniania) i standardu OpenID Connect:

  1. Aby spełniać wymagania protokołu OpenID, musisz podać wartości zakresu openid profile w żądaniu uwierzytelnienia.

    Jeśli chcesz uwzględnić adres e-mail użytkownika, możesz określić dodatkowy zakres wartości email. Aby określić zarówno profile, jak i email, możesz użyć tego parametru w identyfikatorze URI żądania uwierzytelniania:

    scope=openid%20profile%20email
  2. Dodaj token dostępu do nagłówka autoryzacji i wyślij żądanie HTTPS GET do punktu końcowego userinfo, który powinieneś pobrać z dokumentu Discovery, używając wartości metadanych userinfo_endpoint. Odpowiedź userinfo zawiera informacje o użytkowniku zgodnie z opisem w OpenID Connect Standard Claims oraz wartość metadanych claims_supported dokumentu Discovery. Użytkownicy lub ich organizacje mogą udostępnić lub nie udostępnić pewnych pól, więc możesz nie uzyskać informacji z każdego pola w ramach przyznanych uprawnień dostępu.

Dokument opisujący

Protokół OpenID Connect wymaga korzystania z wielu punktów końcowych do uwierzytelniania użytkowników oraz do żądania zasobów, w tym tokenów, informacji o użytkownikach i kluczy publicznych.

Aby uprościć implementację i zwiększyć elastyczność, OpenID Connect umożliwia korzystanie z „dokumentu wyszukiwania”, czyli dokumentu JSON znajdującego się w znanym miejscu i zawierającego pary klucz-wartość, które zawierają szczegółowe informacje o konfiguracji dostawcy OpenID Connect, w tym identyfikatory URI punktów końcowych autoryzacji, tokenów, odwołania, informacji o użytkowniku i kluczy publicznych. Dokument Discovery dla usługi OpenID Connect Google można pobrać z:

https://accounts.google.com/.well-known/openid-configuration

Aby korzystać z usług OpenID Connect Google, musisz zakodować w swojej aplikacji URI dokumentu Discovery (https://accounts.google.com/.well-known/openid-configuration). Aplikacja pobiera dokument, stosuje w odpowiedzi reguły dotyczące buforowania, a potem pobiera z niego identyfikatory URI punktów końcowych w razie potrzeby. Na przykład, aby uwierzytelnić użytkownika, Twój kod pobiera wartość metadanych authorization_endpoint (https://accounts.google.com/o/oauth2/v2/auth w przykładzie poniżej) jako identyfikator URI bazowy dla żądań uwierzytelniania wysyłanych do Google.

Oto przykład takiego dokumentu. Nazwy pól są zgodne ze specyfikacją OpenID Connect Discovery 1.0 (ich znaczenie znajdziesz w tym dokumencie). Wartości są wyłącznie poglądowe i mogą się zmienić, choć są skopiowane z ostatniej wersji dokumentu Google Discovery:

{
  "issuer": "https://accounts.google.com",
  "authorization_endpoint": "https://accounts.google.com/o/oauth2/v2/auth",
  "device_authorization_endpoint": "https://oauth2.googleapis.com/device/code",
  "token_endpoint": "https://oauth2.googleapis.com/token",
  "userinfo_endpoint": "https://openidconnect.googleapis.com/v1/userinfo",
  "revocation_endpoint": "https://oauth2.googleapis.com/revoke",
  "jwks_uri": "https://www.googleapis.com/oauth2/v3/certs",
  "response_types_supported": [
    "code",
    "token",
    "id_token",
    "code token",
    "code id_token",
    "token id_token",
    "code token id_token",
    "none"
  ],
  "subject_types_supported": [
    "public"
  ],
  "id_token_signing_alg_values_supported": [
    "RS256"
  ],
  "scopes_supported": [
    "openid",
    "email",
    "profile"
  ],
  "token_endpoint_auth_methods_supported": [
    "client_secret_post",
    "client_secret_basic"
  ],
  "claims_supported": [
    "aud",
    "email",
    "email_verified",
    "exp",
    "family_name",
    "given_name",
    "iat",
    "iss",
    "locale",
    "name",
    "picture",
    "sub"
  ],
  "code_challenge_methods_supported": [
    "plain",
    "S256"
  ]
}

Możesz uniknąć dwukierunkowego połączenia HTTP, przechowując w pamięci podręcznej wartości z dokumentu Discovery. Używane są standardowe nagłówki HTTP dotyczące pamięci podręcznej i należy je uwzględniać.

Biblioteki klienta

Te biblioteki klienta ułatwiają implementację OAuth 2.0 dzięki integracji z popularnymi frameworkami:

Zgodność z OpenID Connect

System uwierzytelniania OAuth 2.0 Google obsługuje wymagane funkcje ze specyfikacji OpenID Connect Core. Każdy klient zaprojektowany do współpracy z OpenID Connect powinien współpracować z tą usługą (z wyjątkiem obiektu żądania OpenID).