OpenID Connect

Interfejsy API OAuth 2.0 Google mogą być używane zarówno do uwierzytelniania, jak i autoryzacji. W tym dokumencie opisujemy naszą implementację OAuth 2.0 do uwierzytelniania, która jest zgodna ze specyfikacją OpenID Connect i ma certyfikat OpenID. Dokumentacja w artykule Używanie OAuth 2.0 do uzyskiwania dostępu do interfejsów API Google dotyczy również tej usługi. Jeśli chcesz interaktywnie poznać ten protokół, polecamy Google OAuth 2.0 Playground. Aby uzyskać pomoc na Stack Overflow, oznacz swoje pytania tagiem „google-oauth”.

Konfigurowanie protokołu 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  konsoli Google Cloud, aby uzyskać dane logowania OAuth 2.0, ustawić identyfikator URI przekierowania i (opcjonalnie) dostosować informacje o marce, które użytkownicy widzą na ekranie zgody. Możesz też użyć Cloud Console, aby utworzyć konto usługi, włączyć rozliczenia, skonfigurować filtrowanie i wykonać inne zadania. Więcej informacji znajdziesz w Pomocy konsoli Google Cloud.

Uzyskiwanie danych logowania OAuth 2.0

Aby uwierzytelniać użytkowników i uzyskiwać dostęp do interfejsów API Google, potrzebujesz danych logowania OAuth 2.0, w tym identyfikatora klienta i tajnego klucza klienta.

Aby wyświetlić identyfikator klienta i tajny klucz klienta dla danego rodzaju danych uwierzytelniających OAuth 2.0, kliknij ten tekst: Wybierz dane uwierzytelniające. W otwartym oknie wybierz projekt i odpowiednie dane uwierzytelniające, a następnie kliknij Wyświetl.

Możesz też wyświetlić identyfikator i tajny klucz klienta na stronie Klienci w konsoli Cloud:

  1. Otwórz stronę Klienci.
  2. Kliknij nazwę klienta lub ikonę edycji . Identyfikator i obiekt tajny klienta znajdziesz u góry strony.

Ustawianie identyfikatora URI przekierowania

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

Aby utworzyć, wyświetlić lub edytować identyfikatory URI przekierowania dla danych logowania OAuth 2.0, wykonaj te czynności:

  1. Otwórz stronę Klienci.
  2. Kliknij klienta.
  3. Wyświetl lub edytuj identyfikatory URI przekierowania.

Jeśli na stronie Klienci nie ma żadnego klienta, oznacza to, że Twój projekt nie ma danych logowania OAuth. Aby utworzyć klienta, kliknij Utwórz klienta.

Dostosowywanie ekranu zgody użytkownika

W przypadku użytkowników uwierzytelnianie OAuth 2.0 obejmuje ekran zgody, na którym opisane są informacje, które użytkownik udostępnia, oraz obowiązujące warunki. Na przykład podczas logowania użytkownik może zostać poproszony o przyznanie aplikacji dostępu do jego adresu e-mail i podstawowych informacji o koncie. O dostęp do tych informacji możesz poprosić za pomocą parametru scope, który aplikacja uwzględnia w żądaniu uwierzytelnienia. Zakresów możesz też używać do żądania dostępu do innych interfejsów API Google.

Na ekranie zgody użytkownika wyświetlane są też informacje o marce, takie jak nazwa produktu, logo i adres URL strony głównej. Informacje o marce możesz kontrolować w konsoli Cloud.

Aby włączyć ekran zgody w projekcie:

  1. Otwórz stronę Marka w konsoli Google Cloud.
  2. Jeśli pojawi się monit, wybierz projekt lub utwórz nowy.
  3. Wypełnij formularz i kliknij Zapisz.

Poniższe okno z prośbą o zgodę na przetwarzanie danych osobowych pokazuje, co zobaczy użytkownik, gdy w żądaniu występuje kombinacja protokołu OAuth 2.0 i zakresów Dysku Google. (Ten ogólny dialog został wygenerowany za pomocą Google OAuth 2.0 Playground, więc nie zawiera informacji o marce, które byłyby ustawione w Cloud Console).

Przykład strony wyrażania zgody
Rysunek 1. Zrzut ekranu strony zgody

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 związanych z uwierzytelnianiem użytkowników i uzyskiwaniem dostępu do interfejsów API Google. Przykłady to usługi Google Identity Servicesbiblioteki klienta Google, które są dostępne na różnych platformach.

Jeśli zdecydujesz się nie korzystać z biblioteki, postępuj zgodnie z instrukcjami w pozostałej części tego dokumentu, w którym opisano przepływy żądań HTTP, które są podstawą dostępnych bibliotek.

Uwierzytelnianie użytkownika

Uwierzytelnianie użytkownika polega na uzyskaniu tokena tożsamości i jego zweryfikowaniu. Tokeny tożsamości to standardowa funkcja OpenID Connect, która służy do udostępniania w internecie potwierdzeń tożsamości.

Najczęściej stosowane metody uwierzytelniania użytkownika i uzyskiwania tokena identyfikatora to przepływ „serwerowy” i przepływ „niejawny”. Proces po stronie serwera umożliwia serwerowi backendu aplikacji weryfikację tożsamości osoby korzystającej z przeglądarki lub urządzenia mobilnego. Przepływ niejawny jest używany, gdy aplikacja po stronie klienta (zwykle aplikacja JavaScript działająca w przeglądarce) musi mieć bezpośredni dostęp do interfejsów API zamiast korzystać z serwera backendu.

Z tego dokumentu dowiesz się, jak przeprowadzić przepływ po stronie serwera w celu uwierzytelnienia użytkownika. Przepływ niejawny jest znacznie bardziej skomplikowany ze względu na ryzyko związane z bezpieczeństwem obsługi i używania tokenów po stronie klienta. Jeśli musisz wdrożyć przepływ niejawny, zdecydowanie zalecamy korzystanie z Google Identity Services.

Przepływ serwera

Aby umożliwić aplikacji korzystanie z tych protokołów i uwierzytelnianie użytkowników, skonfiguruj ją w konsoli Cloud. Gdy użytkownik spróbuje zalogować się przez Google, musisz:

  1. Tworzenie tokena stanu zabezpieczającego przed fałszerstwem
  2. Wysyłanie do Google prośby o uwierzytelnienie
  3. Potwierdź token stanu zabezpieczający przed fałszerstwem
  4. Wymiana code na token dostępu i token identyfikatora
  5. Pobieranie informacji o użytkowniku z tokena identyfikatora
  6. Uwierzytelnianie użytkownika

1. Tworzenie tokena stanu chroniącego przed fałszerstwem

Musisz chronić bezpieczeństwo 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. Później dopasujesz ten unikalny token sesji do odpowiedzi uwierzytelniania zwróconej przez usługę logowania OAuth Google, aby sprawdzić, czy żądanie pochodzi od użytkownika, a nie od złośliwego atakującego. Te tokeny są często określane jako tokeny CSRF (cross-site request forgery).

Dobrym wyborem w przypadku tokena stanu jest ciąg około 30 znaków utworzony za pomocą generatora liczb losowych wysokiej jakości. Innym jest skrót wygenerowany przez podpisanie niektórych zmiennych stanu sesji za pomocą klucza, który jest przechowywany w tajemnicy na Twoim backendzie.

Poniższy kod pokazuje, jak generować 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 dla 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 do Google żądania uwierzytelnienia

Następnym krokiem jest utworzenie żądania HTTPS GET z odpowiednimi parametrami URI. Zwróć uwagę, że we wszystkich krokach tego procesu używany jest protokół HTTPS, a nie HTTP. Połączenia HTTP są odrzucane. Podstawowy identyfikator URI należy pobrać z dokumentu opisującego Discovery za pomocą wartości metadanych authorization_endpoint. W dalszej części tego omówienia założono, że podstawowy identyfikator URI to https://accounts.google.com/o/oauth2/v2/auth.

W przypadku podstawowego żądania określ te parametry:

  • client_id, który możesz uzyskać na stronie Klienci w Cloud Console.
  • response_type, które w podstawowym żądaniu przepływu kodu autoryzacji powinno mieć wartość code. (Więcej informacji znajdziesz na stronie response_type).
  • scope, która w przypadku podstawowego żądania powinna mieć wartość openid email. (Więcej informacji znajdziesz na stronie scope).
  • redirect_uri powinien być punktem końcowym HTTP na serwerze, który będzie odbierać odpowiedź od Google. Wartość musi dokładnie odpowiadać jednemu z autoryzowanych identyfikatorów URI przekierowania klienta OAuth 2.0, który został skonfigurowany na stronie Dane logowania w konsoli Cloud. Jeśli ta wartość nie pasuje do autoryzowanego identyfikatora URI, żądanie zakończy się niepowodzeniem z błędem redirect_uri_mismatch.
  • state powinien zawierać wartość unikalnego tokena sesji zapobiegającego fałszowaniu, a także wszelkie inne informacje potrzebne do odzyskania kontekstu, gdy użytkownik wróci do aplikacji, np. adres URL strony początkowej. (Więcej informacji znajdziesz na stronie state).
  • nonce to losowa wartość wygenerowana przez aplikację, która w przypadku jej wystąpienia włącza ochronę przed powtórzeniem.
  • login_hint może być adresem e-mail użytkownika lub ciągiem znaków sub, który jest odpowiednikiem identyfikatora Google użytkownika. Jeśli nie podasz login_hint, a użytkownik jest zalogowany, na ekranie zgody pojawi się prośba o zatwierdzenie udostępnienia Twojej aplikacji adresu e-mail użytkownika. (Więcej informacji znajdziesz w login_hint).
  • Użyj parametru hd, aby zoptymalizować proces OpenID Connect dla użytkowników określonej domeny powiązanej z organizacją Google Workspace lub Cloud (więcej informacji znajdziesz na stronie hd).

Oto przykład pełnego identyfikatora URI uwierzytelniania OpenID Connect z podziałami wierszy i spacjami dla lepszej czytelności:

https://accounts.google.com/o/oauth2/v2/auth?
 response_type=code&
 client_id=424911365001.apps.googleusercontent.com&
 scope=openid%20email&
 redirect_uri=https%3A//developers.google.com/oauthplayground&
 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 na ich temat lub o dostęp do konta, na który nie wyrazili wcześniej zgody.

3. Potwierdzenie tokenu stanu zabezpieczającego przed fałszerstwem

Odpowiedź jest wysyłana na adres redirect_uri podany w żądaniu. Wszystkie odpowiedzi są zwracane w ciągu zapytania:

https://developers.google.com/oauthplayground?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

Zgodnie z RFC 6749 klienci MUSZĄ ignorować nierozpoznane parametry odpowiedzi. Na serwerze musisz potwierdzić, że state otrzymany od Google pasuje do tokena sesji utworzonego w kroku 1. Ta weryfikacja w obie strony pomaga potwierdzić, że żądanie wysyła użytkownik, a nie złośliwy skrypt.

Poniższy kod pokazuje, jak potwierdzić tokeny sesji utworzone 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 dla 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 serwer może wymienić na token dostępu i token identyfikatora. Serwer dokonuje tej wymiany, wysyłając żądanie HTTPS POST. Żądanie POST jest wysyłane do punktu końcowego tokena, który należy pobrać z dokumentu wykrywania za pomocą wartości metadanych token_endpoint. W dalszej części tego dokumentu założono, że punkt końcowy to https://oauth2.googleapis.com/token. Żądanie musi zawierać w treści POST te parametry:

Pola
code Kod autoryzacji zwrócony w pierwszym żądaniu.
client_id Identyfikator klienta uzyskany w Cloud Console na stronie Klienci, zgodnie z opisem w artykule Uzyskiwanie danych logowania OAuth 2.0.
client_secret Tajny klucz klienta uzyskany w Cloud Console na stronie Klienci zgodnie z opisem w sekcji Uzyskiwanie danych logowania OAuth 2.0.
redirect_uri Autoryzowany identyfikator URI przekierowania dla danego client_id określonego na stronie Klienci w konsoli Cloud, zgodnie z opisem w artykule Ustawianie identyfikatora URI przekierowania.
grant_type To pole musi zawierać wartość authorization_code, zgodnie ze specyfikacją 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//developers.google.com/oauthplayground&
grant_type=authorization_code

Odpowiedź informująca o powodzeniu 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óre są podpisane cyfrowo przez Google.
scope Zakresy dostępu przyznane przez access_token w postaci listy ciągów znaków rozdzielonych spacjami, w których rozróżniana jest wielkość liter.
token_type Określa typ zwróconego tokena. Obecnie to pole ma zawsze wartość Bearer.
refresh_token (opcjonalnie)

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

5. Pobieranie informacji o użytkowniku z tokena identyfikatora

Token tożsamości to JWT (token sieciowy JSON), czyli obiekt JSON zakodowany w formacie Base64 i podpisany kryptograficznie. Zwykle weryfikacja tokena identyfikatora przed jego użyciem jest bardzo ważna, ale ponieważ komunikujesz się bezpośrednio z Google za pomocą kanału HTTPS bez pośredników i używasz tajnego klucza klienta do uwierzytelniania się w Google, możesz mieć pewność, że otrzymany token rzeczywiście pochodzi z Google i jest ważny. Jeśli serwer przekazuje token identyfikatora do innych komponentów aplikacji, bardzo ważne jest, aby inne komponenty weryfikowały token przed jego użyciem.

Większość bibliotek interfejsu API łączy weryfikację z dekodowaniem wartości zakodowanych w formacie base64url i parsowaniem kodu JSON, więc prawdopodobnie i tak zweryfikujesz token podczas uzyskiwania dostępu do roszczeń w tokenie identyfikatora.

Ładunek tokena identyfikatora

Token tożsamości to obiekt JSON zawierający zbiór par nazwa/wartość. Oto przykład sformatowany w celu zwiększenia czytelności:

{
  "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ć następujące pola (nazywane deklaracjami):

Roszczenie Udostępniony Opis
aud zawsze Odbiorca, dla którego jest przeznaczony dany token tożsamości. Musi to być jeden z identyfikatorów klienta OAuth 2.0 Twojej aplikacji.
exp zawsze Czas wygaśnięcia, po którym token tożsamości 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 nigdy się nie zmienia. Używaj sub w aplikacji jako klucza unikalnego identyfikatora użytkownika. Maksymalna długość to 255 znaków ASCII z uwzględnieniem wielkości liter.
amr Tablica JSON ciągów znaków, które identyfikują metody uwierzytelniania używane do logowania się na konto Google. Jeśli występuje, zawiera co najmniej jedną z tych możliwych wartości:[IANA.AMR]
  • hwk użyto klucza sprzętowego;
  • mfa Uwierzytelnianie wielopoziomowe zostało zakończone
  • pwd użyto hasła
  • sms do weryfikacji użyto SMS-a;
  • swk użyto klucza programowego, takiego jak klucz dostępu.
  • tel do weryfikacji użyto połączenia telefonicznego;
Występuje tylko wtedy, gdy roszczenie amr jest uwzględnione w żądaniu uwierzytelniania i włączone w ustawieniach.
auth_time Czas uwierzytelnienia użytkownika, liczba JSON reprezentująca liczbę sekund, które upłynęły od epoki uniksowej (1 stycznia 1970 r., 00:00:00 UTC). Podawany, gdy deklaracja auth_time jest uwzględniona w żądaniu uwierzytelnienia i włączona w ustawieniach.
at_hash Hash tokena dostępu. Sprawdza, czy token dostępu jest powiązany z tokenem tożsamości. Jeśli token identyfikatora jest wydawany z wartością access_token w przypadku przepływu po stronie serwera, to roszczenie jest zawsze uwzględniane. To roszczenie może być używane jako alternatywny mechanizm ochrony przed atakami typu żądanie z innej witryny, 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 klienta OAuth 2.0client_id, ale są związane z tym samym projektem interfejsów API Google.
email Adres e-mail użytkownika. Wartość jest podawana tylko wtedy, gdy w żądaniu uwzględniono zakres email. Wartość tego roszczenia może nie być unikalna dla tego konta i może się zmieniać z czasem, dlatego nie należy jej używać jako głównego identyfikatora do łączenia z rekordem użytkownika. Nie możesz też polegać na domenie roszczenia email, aby identyfikować użytkowników organizacji Google Workspace lub Cloud. Zamiast tego użyj roszczenia hd.
email_verified Wartość „prawda”, jeśli adres e-mail użytkownika został zweryfikowany. W przeciwnym razie „fałsz”.
family_name Nazwisko użytkownika. Może być podany, gdy występuje roszczenie name.
given_name Imię lub imiona użytkownika. 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 sprawdzić to roszczenie, gdy ograniczasz dostęp do zasobu tylko do członków określonych domen. Brak tego roszczenia oznacza, że konto nie należy do domeny hostowanej przez Google.
locale Lokalizacja użytkownika reprezentowana przez tag języka BCP 47. 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żna go podać, gdy:
  • Zakres żądania zawierał ciąg znaków „profile”
  • Token identyfikatora jest zwracany podczas odświeżania tokena

Gdy występują roszczenia name, możesz ich użyć do zaktualizowania rekordów użytkowników aplikacji. Pamiętaj, że nie ma gwarancji, że to roszczenie będzie obecne.

nonce Wartość nonce dostarczona przez aplikację w żądaniu uwierzytelnienia. Aby chronić się przed atakami typu replay, wyświetlaj tę wartość tylko raz.
picture Adres URL zdjęcia profilowego użytkownika. Można go podać, gdy:
  • Zakres żądania zawierał ciąg znaków „profile”
  • Token identyfikatora jest zwracany podczas odświeżania tokena

Jeśli występują roszczenia picture, możesz ich użyć do zaktualizowania rekordów użytkowników aplikacji. Pamiętaj, że nie ma gwarancji, że to roszczenie będzie obecne.

profile Adres URL strony profilu użytkownika. Można go podać, gdy:
  • Zakres żądania zawierał ciąg znaków „profile”
  • Token identyfikatora jest zwracany podczas odświeżania tokena

Jeśli występują roszczenia profile, możesz ich użyć do zaktualizowania rekordów użytkowników aplikacji. Pamiętaj, że nie ma gwarancji, że to roszczenie będzie obecne.

6. Uwierzytelnianie użytkownika

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

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

Tematy zaawansowane

W kolejnych sekcjach znajdziesz szczegółowe informacje o interfejsie Google OAuth 2.0 API. 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ć uprawnienia do korzystania z innych interfejsów API Google w imieniu użytkownika (np. YouTube, Dysk Google, Kalendarz czy Kontakty) w tym samym czasie, w którym uwierzytelniasz użytkownika. Aby to zrobić, w żądaniu uwierzytelniania wysyłanym do Google uwzględnij inne potrzebne zakresy. Na przykład, aby dodać do żądania uwierzytelniania grupę wiekową użytkownika, przekaż parametr zakresu openid email https://www.googleapis.com/auth/profile.agerange.read. Użytkownik otrzyma odpowiedni komunikat na ekranie zgody. Token dostępu, który otrzymasz od Google, umożliwi aplikacji dostęp do wszystkich interfejsów API powiązanych z zakresami dostępu, o które poprosisz i które zostaną Ci przyznane.

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 korzysta z aplikacji. Aby poprosić o token odświeżania, ustaw parametr access_type na offlineprośbie o uwierzytelnianie.

Uwagi:

  • Token odświeżania należy przechowywać w bezpiecznym i trwałym miejscu, ponieważ można go uzyskać tylko podczas pierwszego wykonania przepływu wymiany kodu.
  • Liczba wydawanych tokenów odświeżania jest ograniczona: jedno ograniczenie dotyczy kombinacji klient/użytkownik, a drugie – użytkownika we wszystkich klientach. Jeśli aplikacja zażąda zbyt wielu tokenów odświeżania, może osiągnąć te limity, w którym to przypadku starsze tokeny odświeżania przestaną działać.

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

Możesz poprosić użytkownika o ponowne autoryzowanie aplikacji, ustawiając parametr prompt na consentżądaniu uwierzytelnienia. Jeśli parametr prompt=consent jest uwzględniony, ekran zgody wyświetla się za każdym razem, gdy aplikacja żąda autoryzacji zakresów dostępu, nawet jeśli wszystkie zakresy zostały wcześniej przyznane 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 w sekcji prompt.

Parametry identyfikatora URI uwierzytelniania

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

Parametr Wymagane Opis
client_id (Wymagane) Ciąg identyfikatora klienta uzyskany w Konsoli Cloud na stronie Klienci, zgodnie z opisem w artykule Uzyskiwanie danych logowania OAuth 2.0.
nonce (Wymagane) Losowa wartość wygenerowana przez aplikację, która umożliwia ochronę przed powtórzeniem.
response_type (Wymagane) Jeśli wartość to code, uruchamia podstawowy przepływ 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 przepływ niejawny, który wymaga użycia JavaScriptu w identyfikatorze URI przekierowania do pobierania tokenów z identyfikatora URI #fragment.
redirect_uri (Wymagane) Określa, gdzie ma zostać wysłana odpowiedź. Wartość tego parametru musi być dokładnie zgodna z jedną z autoryzowanych wartości przekierowania ustawionych na stronie Klienci w konsoli Cloud (w tym schemat HTTP lub HTTPS, wielkość liter i końcowy znak „/”, jeśli występuje).
scope (Wymagane)

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

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

Jeśli występuje wartość zakresu email, token identyfikatora zawiera roszczenia emailemail_verified.

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

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

state (opcjonalne, ale zdecydowanie zalecane)

Nieprzejrzysty ciąg znaków, który jest przesyłany w obie strony w protokole, tzn. jest zwracany jako parametr URI w przypadku przepływu podstawowego i jako identyfikator URI #fragment w przypadku przepływu niejawnego.

Parametr state może być przydatny do powiązania żądań i odpowiedzi. Ponieważ wartość parametru redirect_uri można odgadnąć, użycie wartości state może zwiększyć pewność, że przychodzące połączenie jest wynikiem żądania uwierzytelniania zainicjowanego przez aplikację. Jeśli wygenerujesz losowy ciąg znaków lub zakodujesz w tej zmiennej state skrót stanu klienta (np. pliku cookie), możesz zweryfikować odpowiedź, aby sprawdzić, czy żądanie i odpowiedź pochodzą z tej samej 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 opisany w sekcji Dostęp offline. Jeśli klient prosi o token dostępu, nie otrzymuje tokena odświeżania, chyba że określono wartość offline.
claims (Opcjonalnie) Parametr claims służy do określania co najmniej jednego pola opcjonalnego, które ma być uwzględnione w odpowiedziach z punktu końcowego userinfo lub w odpowiedziach z tokenem identyfikatora żądania uwierzytelniania. Wartość jest obiektem JSON zawierającym typ odpowiedzi i żądane roszczenia. Serwery Google akceptują te żądania roszczeń:
Żądania dotyczące roszczeń
amr Żądanie metody użytej podczas ostatniego uwierzytelniania użytkownika. Aby zwrócić amr jako pole w odpowiedzi tokena identyfikatora, uwzględnij parametr żądania claims:claims={"id_token":{"amr":{"essential":true}}}Musi być włączony w ustawieniach.
auth_time Poproś o czas ostatniego uwierzytelnienia użytkownika. Aby zwrócić auth_time jako pole w odpowiedzi tokena identyfikatora, uwzględnij parametr żądania claims:claims={"id_token":{"auth_time":{"essential":true}}}Musi być włączony w ustawieniach.
display (Opcjonalnie) Ciąg znaków ASCII określający, jak serwer autoryzacji wyświetla strony interfejsu uwierzytelniania i zgody użytkownika. Podane niżej wartości są określone i akceptowane przez serwery Google, ale nie mają wpływu na zachowanie przepływu protokołu: page, popup, touchwap.
hd (Opcjonalnie)

Uprość proces logowania na konta należące do organizacji Google Cloud. Podają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 pod kątem kont organizacji Google Cloud ogólnie, a nie tylko jednej domeny organizacji Google Cloud, ustaw wartość gwiazdki (*): hd=*.

Nie polegaj na tej optymalizacji interfejsu, aby kontrolować, kto ma dostęp do aplikacji, ponieważ żądania po stronie klienta można modyfikować. Upewnij się, że zweryfikowany zwrócony token identyfikatora ma wartość roszczenia hd, która jest zgodna z oczekiwaną wartością (np. mycolledge.edu). W przeciwieństwie do parametru żądania roszczenie hd tokena identyfikatora jest zawarte w tokenie zabezpieczeń od Google, więc wartość jest wiarygodna.

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

Pamiętaj, że w przypadku przepływu aplikacji instalowanej nie możesz przeprowadzić autoryzacji przyrostowej.

login_hint (Opcjonalnie) Gdy aplikacja wie, którego użytkownika próbuje uwierzytelnić, może przekazać ten parametr jako wskazówkę do serwera uwierzytelniania. Przekazanie tej wskazówki powoduje pominięcie selektora konta i wstępne wypełnienie pola adresu e-mail w formularzu logowania lub wybranie odpowiedniej sesji (jeśli użytkownik korzysta z wielokrotnego logowania), co może pomóc uniknąć problemów, które występują, gdy aplikacja loguje 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 odpowiednikiem identyfikatora Google użytkownika.
prompt (Opcjonalnie) Lista wartości ciągów znaków oddzielonych spacjami, która określa, czy serwer autoryzacji wyświetla użytkownikowi prośbę o ponowne uwierzytelnienie i wyrażenie zgody. Możliwe wartości:
  • none

    Serwer autoryzacji nie wyświetla żadnych ekranów uwierzytelniania ani zgody użytkownika. Jeśli użytkownik nie jest jeszcze uwierzytelniony i nie skonfigurował wcześniej zgody na żądane zakresy, serwer zwróci błąd. Możesz użyć parametru none, aby sprawdzić, czy uwierzytelnianie lub zgoda już istnieją.

  • consent

    Serwer autoryzacji prosi użytkownika o zgodę przed przekazaniem informacji do klienta.

  • select_account

    Serwer autoryzacji wyświetla użytkownikowi prośbę o wybranie konta. Umożliwia to użytkownikowi, który ma na serwerze autoryzacji kilka kont, wybranie jednego z nich, na którym ma aktywną sesję.

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

hl (Opcjonalnie) Tag języka BCP 47 używany do określania języka wyświetlania na ekranach logowania, wyboru konta i zgody. Jeśli ten parametr nie zostanie podany, język zostanie wybrany na podstawie ustawień konta Google lub przeglądarki użytkownika. Aby na przykład poprosić o interfejs w języku angielskim (wersja brytyjska), ustaw parametr na en-GB.

Weryfikowanie tokena tożsamości

Musisz zweryfikować wszystkie tokeny identyfikatora na serwerze, chyba że wiesz, że pochodzą one bezpośrednio z Google. Na przykład serwer musi potwierdzać autentyczność wszystkich tokenów identyfikatora otrzymywanych z aplikacji klienckich.

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

  • Wysyłanie tokenów tożsamości z żądaniami, które wymagają uwierzytelnienia. Tokeny identyfikatora informują, który użytkownik wysyła żądanie i dla którego klienta został przyznany token identyfikatora.

Tokeny identyfikatora są poufne i mogą zostać wykorzystane w nieodpowiedni sposób, jeśli zostaną przechwycone. Musisz zadbać o bezpieczne przetwarzanie tych tokenów, przesyłając je tylko za pomocą protokołu HTTPS i tylko w danych POST lub w nagłówkach żądań. Jeśli przechowujesz tokeny identyfikacyjne na serwerze, musisz też zadbać o ich bezpieczeństwo.

Tokeny identyfikacyjne są przydatne, ponieważ można je przekazywać między różnymi komponentami aplikacji. Komponenty te mogą używać tokena identyfikacyjnego jako prostego mechanizmu uwierzytelniania, który uwierzytelnia aplikację i użytkownika. Zanim jednak użyjesz informacji w tokenie identyfikatora lub potraktujesz go jako potwierdzenie, że użytkownik został uwierzytelniony, musisz go zweryfikować.

Weryfikacja tokena tożsamości wymaga kilku kroków:

  1. Sprawdź, czy token identyfikatora jest prawidłowo podpisany przez wystawcę. Tokeny wydane przez Google są podpisywane przy użyciu jednego z certyfikatów znajdujących się pod identyfikatorem URI określonym w wartości metadanych jwks_uridokumencie opisującym Discovery.
  2. Sprawdź, czy wartość roszczenia iss w tokenie identyfikatora jest równa https://accounts.google.com lub accounts.google.com.
  3. Sprawdź, czy wartość roszczenia aud w tokenie identyfikatora jest równa identyfikatorowi klienta aplikacji.
  4. Sprawdź, czy czas wygaśnięcia (deklaracja exp) tokena identyfikatora nie minął.
  5. Jeśli w żądaniu podano wartość parametru hd, sprawdź, czy token identyfikatora zawiera roszczenie hd, które pasuje do zaakceptowanej domeny powiązanej z organizacją Google Cloud.

Kroki 2–5 obejmują tylko porównania ciągów znaków i dat, które są dość proste, więc nie będziemy ich tutaj szczegółowo opisywać.

Pierwszy krok jest bardziej złożony i obejmuje sprawdzanie podpisu kryptograficznego. Na potrzeby debugowania możesz użyć punktu końcowego tokeninfo Google, aby porównać go z lokalnym przetwarzaniem zaimplementowanym na serwerze lub urządzeniu. Załóżmy, że wartość tokena identyfikatora to XYZ123. Następnie cofniesz odwołanie do identyfikatora URI https://oauth2.googleapis.com/tokeninfo?id_token=XYZ123. Jeśli podpis tokena jest prawidłowy, odpowiedzią będzie ładunek JWT w postaci zdekodowanego obiektu JSON.

Punkt końcowy tokeninfo jest przydatny do debugowania, ale w środowisku produkcyjnym pobieraj klucze publiczne Google z punktu końcowego keys i przeprowadzaj weryfikację lokalnie. Identyfikator URI kluczy należy pobrać z dokumentu opisującego Discovery za pomocą wartości metadanych jwks_uri. Żądania wysyłane do punktu końcowego debugowania mogą być ograniczane lub podlegać okresowym błędom.

Klucze publiczne Google zmieniają się rzadko, więc możesz je buforować za pomocą dyrektyw pamięci podręcznej odpowiedzi HTTP i w większości przypadków przeprowadzać lokalną weryfikację znacznie wydajniej niż za pomocą punktu końcowego tokeninfo. Wymaga to pobrania i przeanalizowania certyfikatów oraz wykonania odpowiednich wywołań kryptograficznych w celu sprawdzenia podpisu. Na szczęście w wielu językach dostępne są dobrze przetestowane biblioteki, które to umożliwiają (zobacz jwt.io).

Uzyskiwanie informacji profilowych użytkownika

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

  1. Aby zachować zgodność z OpenID, musisz uwzględnić wartości zakresu openid profileżądaniu uwierzytelnienia.

    Jeśli chcesz, aby adres e-mail użytkownika był uwzględniany, możesz podać dodatkową wartość zakresu email. Aby określić zarówno profile, jak i email, możesz w identyfikatorze URI żądania uwierzytelniania umieścić ten parametr:

    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 należy pobrać z dokumentu opisującego Discovery za pomocą wartości metadanych userinfo_endpoint. Odpowiedź userinfo zawiera informacje o użytkowniku, zgodnie z opisem w OpenID Connect Standard Claims i wartości metadanych claims_supported w dokumencie Discovery. Użytkownicy lub ich organizacje mogą podawać lub pomijać niektóre pola, więc w przypadku autoryzowanych zakresów dostępu możesz nie uzyskać informacji o każdym polu.

Dokument opisujący

Protokół OpenID Connect wymaga używania wielu punktów końcowych do uwierzytelniania użytkowników i wysyłania żądań dotyczących zasobów, w tym tokenów, informacji o użytkowniku i kluczy publicznych.

Aby uprościć implementacje i zwiększyć elastyczność, OpenID Connect umożliwia korzystanie z „dokumentu opisującego”, czyli dokumentu JSON znajdującego się w dobrze znanym miejscu, który zawiera pary klucz-wartość z informacjami o konfiguracji dostawcy OpenID Connect, w tym identyfikatory URI punktów końcowych autoryzacji, tokena, odwoływania, informacji o użytkowniku i kluczy publicznych. Dokument opisujący usługę OpenID Connect Google można pobrać z tego adresu:

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

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

Oto przykład takiego dokumentu. Nazwy pól są zgodne z nazwami określonymi w specyfikacji OpenID Connect Discovery 1.0 (ich znaczenie znajdziesz w tym dokumencie). Wartości mają charakter wyłącznie ilustracyjny i mogą ulec zmianie, chociaż są skopiowane z ostatniej wersji rzeczywistego dokumentu opisującego 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ąć podróży w obie strony HTTP, zapisując w pamięci podręcznej wartości z dokumentu opisującego Discovery. Używane są standardowe nagłówki HTTP dotyczące przechowywania w pamięci podręcznej, które należy uwzględniać.

Biblioteki klienta

Te biblioteki klienta ułatwiają wdrażanie OAuth 2.0 dzięki integracji z popularnymi platformami:

Zgodność z OpenID Connect

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