OAuth 2.0 na potrzeby aplikacji internetowych po stronie klienta

Ten dokument wyjaśnia, jak wdrożyć autoryzację OAuth 2.0, aby uzyskać dostęp do interfejsów API Google z aplikacji internetowej w JavaScript. OAuth 2.0 umożliwia użytkownikom udostępnianie określonych danych aplikacji przy jednoczesnym zachowaniu poufności nazw, haseł i innych informacji. Na przykład aplikacja może używać protokołu OAuth 2.0, aby uzyskać od użytkowników uprawnienia do przechowywania plików na ich Dysku Google.

Ten przepływ OAuth 2.0 nazywa się niejawnym przepływem przyznawania. Jest przeznaczony dla aplikacji, które uzyskują dostęp do interfejsów API tylko wtedy, gdy użytkownik korzysta z aplikacji. Te aplikacje nie mogą przechowywać informacji poufnych.

W tym procesie aplikacja otwiera adres URL Google, który używa parametrów zapytania do identyfikowania aplikacji i rodzaju dostępu do interfejsu API, jakiego wymaga aplikacja. URL możesz otworzyć w bieżącym oknie przeglądarki lub w wyskakującym okienku. Użytkownik może uwierzytelnić się w Google i przyznać wymagane uprawnienia. Następnie Google przekierowuje użytkownika z powrotem do Twojej aplikacji. Przekierowanie zawiera token dostępu, który Twoja aplikacja weryfikuje, a następnie wykorzystuje do wysyłania żądań do interfejsu API.

Biblioteka klienta interfejsów API Google i usługi Google Identity

Jeśli do wykonywania autoryzowanych wywołań Google używasz biblioteki klienta interfejsów API Google w JavaScript, do obsługi procesu OAuth 2.0 używaj biblioteki JavaScript Google Identity Services. Zapoznaj się z modelem tokenów usług tożsamości Google, który jest oparty na procesie niejawnego przyznawania protokołu OAuth 2.0.

Wymagania wstępne

Włączanie interfejsów API w projekcie

Każda aplikacja, która wywołuje interfejsy API Google, musi włączyć te interfejsy w  API Console.

Aby włączyć interfejs API w projekcie:

  1. Open the API Library w  Google API Console.
  2. If prompted, select a project, or create a new one.
  3. Zawiera ona listę wszystkich dostępnych interfejsów API pogrupowanych według rodziny usług i popularności. API Library Jeśli interfejs API, który chcesz włączyć, nie jest widoczny na liście, użyj wyszukiwarki, aby go znaleźć, lub kliknij Wyświetl wszystkie w grupie produktów, do której należy.
  4. Wybierz interfejs API, który chcesz włączyć, a następnie kliknij przycisk Włącz.
  5. If prompted, enable billing.
  6. If prompted, read and accept the API's Terms of Service.

Tworzenie danych uwierzytelniających

Każda aplikacja, która używa OAuth 2.0 do uzyskiwania dostępu do interfejsów API Google, musi mieć dane logowania autoryzacji, które identyfikują aplikację na serwerze OAuth 2.0 Google. Poniżej znajdziesz instrukcje tworzenia danych logowania do projektu. Aplikacje mogą następnie używać tych danych logowania do uzyskiwania dostępu do interfejsów API włączonych w tym projekcie.

  1. Go to the Credentials page.
  2. Kliknij Utwórz klienta.
  3. Wybierz typ aplikacji Aplikacja internetowa.
  4. Wypełnij formularz. Aplikacje, które używają JavaScriptu do wysyłania autoryzowanych żądań interfejsu API Google, muszą określać autoryzowane źródła JavaScriptu. Pochodzenia identyfikują domeny, z których aplikacja może wysyłać żądania do serwera OAuth 2.0. Te źródła muszą być zgodne z zasadami weryfikacji Google.

Określanie zakresów dostępu

Zakresy umożliwiają aplikacji żądanie dostępu tylko do potrzebnych jej zasobów, a użytkownikom – kontrolowanie zakresu dostępu przyznawanego aplikacji. Dlatego może istnieć odwrotna zależność między liczbą żądanych zakresów a prawdopodobieństwem uzyskania zgody użytkownika.

Zanim zaczniesz wdrażać autoryzację OAuth 2.0, zalecamy określenie zakresów, do których Twoja aplikacja będzie potrzebować dostępu.

Dokument Zakresy interfejsu API OAuth 2.0 zawiera pełną listę zakresów, których możesz używać do uzyskiwania dostępu do interfejsów API Google.

Uzyskiwanie tokenów dostępu OAuth 2.0

Poniższe kroki pokazują, jak aplikacja wchodzi w interakcję z serwerem OAuth 2.0 Google, aby uzyskać zgodę użytkownika na wykonanie żądania interfejsu API w jego imieniu. Zanim aplikacja będzie mogła wykonać żądanie interfejsu API Google, które wymaga autoryzacji użytkownika, musi uzyskać jego zgodę.

Krok 1. Przekieruj na serwer OAuth 2.0 Google

Aby poprosić o zezwolenie na dostęp do danych użytkownika, przekieruj go na serwer OAuth 2.0 Google.

Punkty końcowe OAuth 2.0

Wygeneruj adres URL, aby wysłać żądanie dostępu z punktu końcowego OAuth 2.0 Google pod adresem https://accounts.google.com/o/oauth2/v2/auth. Ten punkt końcowy jest dostępny przez HTTPS; połączenia przez zwykły protokół HTTP są odrzucane.

Serwer autoryzacji Google obsługuje te parametry ciągu zapytania w przypadku aplikacji serwera internetowego:

Parametry
client_id Wymagany

Identyfikator klienta Twojej aplikacji. Tę wartość znajdziesz w  .

redirect_uri Wymagany

Określa, dokąd serwer API przekierowuje użytkownika po zakończeniu procesu autoryzacji. Wartość musi być dokładnie taka sama jak jeden z autoryzowanych identyfikatorów URI przekierowania dla klienta OAuth 2.0, który został skonfigurowany w  . Jeśli ta wartość nie pasuje do autoryzowanego identyfikatora URI przekierowania dla podanego parametru client_id, pojawi się błąd redirect_uri_mismatch.

Pamiętaj, że schemat http lub https, wielkość liter i ukośnik na końcu („/”) muszą być identyczne.

response_type Wymagany

Aplikacje w JavaScript muszą ustawić wartość parametru na token. Ta wartość nakazuje serwerowi autoryzacji Google zwrócenie tokena dostępu jako pary name=value w identyfikatorze fragmentu identyfikatora URI (#), do którego użytkownik jest przekierowywany po zakończeniu procesu autoryzacji.

scope Wymagany

Lista zakresów oddzielonych spacjami, które identyfikują zasoby, do których aplikacja może uzyskać dostęp w imieniu użytkownika. Te wartości informują ekran zgody, który Google wyświetla użytkownikowi.

Zakresy umożliwiają aplikacji żądanie dostępu tylko do potrzebnych zasobów, a użytkownikom – kontrolowanie zakresu dostępu przyznawanego aplikacji. Dlatego istnieje odwrotna zależność między liczbą żądanych zakresów a prawdopodobieństwem uzyskania zgody użytkownika.

Zalecamy, aby aplikacja prosiła o dostęp do zakresów autoryzacji w kontekście, gdy tylko jest to możliwe. Prosząc o dostęp do danych użytkownika w odpowiednim kontekście za pomocą uwierzytelniania stopniowego, pomagasz użytkownikom łatwiej zrozumieć, dlaczego Twoja aplikacja potrzebuje dostępu, o który prosi.

state Zalecane

Określa dowolną wartość ciągu znaków, której aplikacja używa do utrzymywania stanu między żądaniem autoryzacji a odpowiedzią serwera autoryzacji. Serwer zwraca dokładną wartość, którą wysyłasz jako parę name=value w identyfikatorze fragmentu adresu URL (#) redirect_uri po tym, jak użytkownik wyrazi zgodę na żądanie dostępu do aplikacji lub je odrzuci.

Możesz używać tego parametru do różnych celów, np. do kierowania użytkownika do odpowiedniego zasobu w aplikacji, wysyłania wartości nonce i ograniczania ryzyka związanego z fałszowaniem żądań z innych witryn. Ponieważ wartość redirect_uri można odgadnąć, użycie wartości state może zwiększyć pewność, że przychodzące połączenie jest wynikiem żądania uwierzytelnienia. Jeśli wygenerujesz losowy ciąg znaków lub zakodujesz hash pliku cookie albo inną wartość, która rejestruje stan klienta, możesz zweryfikować odpowiedź, aby dodatkowo upewnić się, że żądanie i odpowiedź pochodzą z tej samej przeglądarki. Zapewni to ochronę przed atakami, takimi jak fałszowanie żądań między witrynami. Przykład tworzenia i potwierdzania tokena state znajdziesz w dokumentacji OpenID Connect.

include_granted_scopes Opcjonalny

Umożliwia aplikacjom korzystanie z autoryzacji stopniowej w celu zgłaszania w odpowiednim kontekście próśb o dostęp do dodatkowych zakresów. Jeśli ustawisz wartość tego parametru na true i żądanie autoryzacji zostanie zaakceptowane, nowy token dostępu będzie obejmować również wszystkie zakresy, do których użytkownik wcześniej przyznał aplikacji dostęp. Przykłady znajdziesz w sekcji Autoryzacja przyrostowa.

login_hint Opcjonalny

Jeśli Twoja aplikacja wie, który użytkownik próbuje się uwierzytelnić, może użyć tego parametru, aby przekazać podpowiedź serwerowi uwierzytelniania Google. Serwer używa wskazówki, aby uprościć proces logowania, wstępnie wypełniając pole z adresem e-mail w formularzu logowania lub wybierając odpowiednią sesję logowania wielokrotnego.

Ustaw wartość parametru na adres e-mail lub identyfikator sub, który jest odpowiednikiem identyfikatora Google użytkownika.

prompt Opcjonalny

Lista promptów rozdzielonych spacjami, w której rozróżniana jest wielkość liter, które mają być wyświetlane użytkownikowi. Jeśli nie określisz tego parametru, użytkownik zobaczy prośbę tylko przy pierwszym żądaniu dostępu przez Twój projekt. Więcej informacji znajdziesz w artykule Ponowne proszenie użytkowników o zgodę.

Możliwe wartości to:

none Nie wyświetlaj żadnych ekranów uwierzytelniania ani zgody. Nie można jej określać z innymi wartościami.
consent Poproś użytkownika o zgodę.
select_account Poproś użytkownika o wybranie konta.

Przykładowe przekierowanie na serwer autoryzacji Google

Poniżej znajduje się przykładowy adres URL z podziałem na wiersze i spacjami dla większej czytelności.

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly%20https%3A//www.googleapis.com/auth/calendar.readonly&
 include_granted_scopes=true&
 response_type=token&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

Po utworzeniu adresu URL żądania przekieruj na niego użytkownika.

Przykładowy kod JavaScript

Poniższy fragment kodu JavaScript pokazuje, jak zainicjować proces autoryzacji w JavaScript bez użycia biblioteki klienta interfejsów API Google w JavaScript. Ten punkt końcowy OAuth 2.0 nie obsługuje współdzielenia zasobów pomiędzy serwerami z różnych domen (CORS), więc fragment kodu tworzy formularz, który otwiera żądanie do tego punktu końcowego.

/*
 * 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_REDIRECT_URI',
                'response_type': 'token',
                'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.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();
}

Krok 2. Google prosi użytkownika o zgodę

Na tym etapie użytkownik decyduje, czy przyznać aplikacji żądany dostęp. Na tym etapie Google wyświetla okno zgody, w którym podaje nazwę aplikacji i usługi interfejsu API Google, do których aplikacja chce uzyskać dostęp za pomocą danych logowania użytkownika, oraz podsumowanie zakresów dostępu, które mają zostać przyznane. Użytkownik może wtedy wyrazić zgodę na przyznanie dostępu do co najmniej jednego zakresu, o który prosi aplikacja, lub odrzucić prośbę.

Na tym etapie aplikacja nie musi nic robić, ponieważ czeka na odpowiedź z serwera Google OAuth 2.0, która będzie wskazywać, czy przyznano dostęp. Odpowiedź jest wyjaśniona w kolejnym kroku.

Błędy

Żądania wysyłane do punktu końcowego autoryzacji OAuth 2.0 Google mogą wyświetlać komunikaty o błędach widoczne dla użytkownika zamiast oczekiwanych procesów uwierzytelniania i autoryzacji. Poniżej znajdziesz listę typowych kodów błędów i sugerowanych rozwiązań.

admin_policy_enforced

Konto Google nie może autoryzować co najmniej jednego z zakresów, o które prosisz, ze względu na zasady administratora Google Workspace. Więcej informacji o tym, jak administrator może ograniczyć dostęp do wszystkich zakresów lub zakresów wrażliwych i ograniczonych, dopóki dostęp nie zostanie wyraźnie przyznany identyfikatorowi klienta OAuth, znajdziesz w artykule pomocy dla administratorów Google Workspace Określanie, które aplikacje innych firm i aplikacje wewnętrzne mają dostęp do danych Google Workspace.

disallowed_useragent

Punkt końcowy autoryzacji jest wyświetlany w osadzonym agencie użytkownika, który jest niedozwolony zgodnie z zasadami Google dotyczącymi protokołu OAuth 2.0.

Android

Deweloperzy aplikacji na Androida mogą napotkać ten komunikat o błędzie podczas otwierania próśb o autoryzację w android.webkit.WebView. Deweloperzy powinni zamiast tego używać bibliotek Androida, takich jak Logowanie przez Google na Androidzie lub AppAuth na Androida od OpenID Foundation.

Deweloperzy stron internetowych mogą napotkać ten błąd, gdy aplikacja na Androida otworzy ogólny link do strony internetowej w osadzonym agencie użytkownika, a użytkownik przejdzie z Twojej witryny do punktu końcowego autoryzacji OAuth 2.0 w Google. Deweloperzy powinni zezwalać na otwieranie ogólnych linków w domyślnym programie obsługi linków w systemie operacyjnym, który obejmuje programy obsługi linków do aplikacji na Androida lub domyślną aplikację przeglądarki. Obsługiwana jest też biblioteka kart niestandardowych Chrome na Androida.

iOS

Deweloperzy aplikacji na iOS i macOS mogą napotkać ten błąd podczas otwierania próśb o autoryzację w WKWebView. Deweloperzy powinni zamiast tego używać bibliotek iOS, takich jak Logowanie przez Google na iOS lub AppAuth na iOS od OpenID Foundation.

Deweloperzy stron internetowych mogą napotkać ten błąd, gdy aplikacja na iOS lub macOS otworzy ogólny link internetowy w osadzonym agencie użytkownika, a użytkownik przejdzie z Twojej witryny do punktu końcowego autoryzacji OAuth 2.0 Google. Deweloperzy powinni zezwalać na otwieranie ogólnych linków w domyślnym programie obsługi linków w systemie operacyjnym, który obejmuje programy obsługi linków uniwersalnych lub domyślną aplikację przeglądarki. Obsługiwana jest też biblioteka SFSafariViewController.

org_internal

Identyfikator klienta OAuth w żądaniu jest częścią projektu, który ogranicza dostęp do kont Google w określonej organizacji Google Cloud. Więcej informacji o tej opcji konfiguracji znajdziesz w sekcji Typ użytkownika w artykule Konfigurowanie ekranu zgody OAuth.

invalid_client

Źródło, z którego wysłano żądanie, nie jest autoryzowane w przypadku tego klienta. Zobacz origin_mismatch.

deleted_client

Klient OAuth używany do wysyłania żądania został usunięty. Usuwanie może odbywać się ręcznie lub automatycznie w przypadku nieużywanych klientów . Usuniętych klientów można przywrócić w ciągu 30 dni od usunięcia. Więcej informacji

invalid_grant

W przypadku autoryzacji przyrostowej token mógł wygasnąć lub zostać unieważniony. Ponownie uwierzytelnij użytkownika i poproś go o zgodę na uzyskanie nowych tokenów. Jeśli ten błąd nadal występuje, sprawdź, czy aplikacja jest prawidłowo skonfigurowana i czy w żądaniu używasz prawidłowych tokenów i parametrów. W przeciwnym razie konto użytkownika mogło zostać usunięte lub wyłączone.

origin_mismatch

Schemat, domena lub port JavaScriptu, z którego pochodzi żądanie autoryzacji, mogą nie pasować do autoryzowanego identyfikatora URI źródła JavaScriptu zarejestrowanego dla identyfikatora klienta OAuth. Sprawdź autoryzowane źródła JavaScriptu w  .

redirect_uri_mismatch

Parametr redirect_uri przekazany w żądaniu autoryzacji nie pasuje do autoryzowanego identyfikatora URI przekierowania dla identyfikatora klienta OAuth. Sprawdź autoryzowane identyfikatory URI przekierowania w sekcji .

Schemat, domena lub port JavaScriptu, z którego pochodzi żądanie autoryzacji, mogą nie pasować do autoryzowanego identyfikatora URI źródła JavaScriptu zarejestrowanego dla identyfikatora klienta OAuth. Sprawdź autoryzowane źródła JavaScriptu w sekcji .

Parametr redirect_uri może odnosić się do przepływu OAuth poza pasmem (OOB), który został wycofany i nie jest już obsługiwany. Aby zaktualizować integrację, zapoznaj się z przewodnikiem po migracji.

invalid_request

W wysłanym przez Ciebie żądaniu wystąpił błąd. Może to wynikać z kilku przyczyn:

  • Żądanie nie zostało prawidłowo sformatowane
  • W prośbie brakowało wymaganych parametrów
  • Żądanie używa metody autoryzacji, której Google nie obsługuje. Sprawdź, czy Twoja integracja OAuth korzysta z zalecanej metody integracji.

Krok 3. Przetwórz odpowiedź serwera OAuth 2.0

Punkty końcowe OAuth 2.0

Serwer OAuth 2.0 wysyła odpowiedź na adres redirect_uri podany w żądaniu tokena dostępu.

Jeśli użytkownik zatwierdzi prośbę, odpowiedź będzie zawierać token dostępu. Jeśli użytkownik nie zatwierdzi prośby, odpowiedź będzie zawierać komunikat o błędzie. Token dostępu lub komunikat o błędzie jest zwracany w części skrótu identyfikatora URI przekierowania, jak pokazano poniżej:

  • Odpowiedź tokena dostępu:

    https://oauth2.example.com/callback#access_token=4/P7q7W91&token_type=Bearer&expires_in=3600

    Oprócz parametru access_token ciąg fragmentu zawiera też parametr token_type, który jest zawsze ustawiony na Bearer, oraz parametr expires_in, który określa czas życia tokena w sekundach. Jeśli w żądaniu tokena dostępu został podany parametr state, jego wartość jest też uwzględniana w odpowiedzi.

  • Odpowiedź o błędzie:
    https://oauth2.example.com/callback#error=access_denied

Przykładowa odpowiedź serwera OAuth 2.0

Możesz przetestować ten proces, klikając ten przykładowy adres URL, który wysyła żądanie dostępu tylko do odczytu w celu wyświetlania metadanych plików na Dysku Google oraz dostępu tylko do odczytu w celu wyświetlania wydarzeń w Kalendarzu Google:

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly%20https%3A//www.googleapis.com/auth/calendar.readonly&
 include_granted_scopes=true&
 response_type=token&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

Po zakończeniu procesu OAuth 2.0 przekierujemy Cię na stronę http://localhost/oauth2callback. Ten adres URL spowoduje wyświetlenie błędu 404 NOT FOUND, chyba że na Twoim komputerze lokalnym znajduje się plik pod tym adresem. W następnym kroku znajdziesz więcej informacji o danych zwracanych w identyfikatorze URI, gdy użytkownik zostanie przekierowany z powrotem do Twojej aplikacji.

Krok 4. Sprawdź, które zakresy użytkownicy przyznali aplikacji

Gdy prosisz o wiele uprawnień (zakresów), użytkownicy mogą nie przyznać aplikacji dostępu do wszystkich z nich. Aplikacja musi sprawdzać, które zakresy zostały faktycznie przyznane, i prawidłowo obsługiwać sytuacje, w których niektóre uprawnienia są odrzucane. Zazwyczaj polega to na wyłączaniu funkcji, które korzystają z tych odrzuconych zakresów.

Są jednak wyjątki. Aplikacje Google Workspace Enterprise z delegowaniem uprawnień w całej domenie lub aplikacje oznaczone jako zaufane pomijają ekran zgody na szczegółowe uprawnienia. W przypadku tych aplikacji użytkownicy nie zobaczą ekranu z prośbą o zgodę na poszczególne uprawnienia. Zamiast tego aplikacja otrzyma wszystkie żądane zakresy lub nie otrzyma żadnego z nich.

Więcej informacji znajdziesz w artykule Jak zarządzać szczegółowymi uprawnieniami.

Punkty końcowe OAuth 2.0

Aby sprawdzić, czy użytkownik przyznał Twojej aplikacji dostęp do określonego zakresu, sprawdź pole scope w odpowiedzi tokena dostępu. Zakresy dostępu przyznane przez token dostępu wyrażone jako lista ciągów znaków oddzielonych spacjami, w których wielkość liter ma znaczenie.

Na przykład poniższa przykładowa odpowiedź z tokenem dostępu wskazuje, że użytkownik przyznał Twojej aplikacji dostęp do uprawnień do odczytu aktywności na Dysku i wydarzeń w Kalendarzu:

  {
    "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
    "expires_in": 3920,
    "token_type": "Bearer",
    "scope": "https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly",
    "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
  }

Wywoływanie interfejsów API Google

Punkty końcowe OAuth 2.0

Gdy aplikacja uzyska token dostępu, może go używać do wywoływania interfejsu API Google w imieniu danego konta użytkownika, jeśli zakresy dostępu wymagane przez interfejs API zostały przyznane. Aby to zrobić, dołącz token dostępu do żądania wysyłanego do interfejsu API, uwzględniając parametr zapytania access_token lub wartość nagłówka HTTP AuthorizationBearer. W miarę możliwości preferowany jest nagłówek HTTP, ponieważ ciągi zapytań są zwykle widoczne w logach serwera. W większości przypadków możesz użyć biblioteki klienta, aby skonfigurować wywołania interfejsów API Google (np. podczas wywoływania interfejsu Drive Files API).

Wszystkie interfejsy API Google i ich zakresy możesz wypróbować na stronie OAuth 2.0 Playground.

Przykłady żądań HTTP GET

Wywołanie punktu końcowego drive.files (interfejs Drive Files API) za pomocą nagłówka HTTP Authorization: Bearer może wyglądać tak: Pamiętaj, że musisz podać własny token dostępu:

GET /drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token

Oto wywołanie tego samego interfejsu API dla uwierzytelnionego użytkownika za pomocą parametru ciągu zapytania access_token:

GET https://www.googleapis.com/drive/v2/files?access_token=access_token

curl przykładu

Możesz przetestować te polecenia za pomocą aplikacji wiersza poleceń curl. Oto przykład, w którym użyto opcji nagłówka HTTP (preferowanej):

curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files

Możesz też wybrać opcję parametru ciągu zapytania:

curl https://www.googleapis.com/drive/v2/files?access_token=access_token

Przykładowy kod JavaScript

Poniższy fragment kodu pokazuje, jak za pomocą CORS (Cross-origin resource sharing) wysłać żądanie do interfejsu API Google. Ten przykład nie korzysta z biblioteki klienta interfejsów API Google dla JavaScriptu. Nawet jeśli nie używasz biblioteki klienta, przewodnik CORS support w dokumentacji tej biblioteki prawdopodobnie pomoże Ci lepiej zrozumieć te żądania.

W tym fragmencie kodu zmienna access_token reprezentuje token uzyskany do wysyłania żądań do interfejsu API w imieniu autoryzowanego użytkownika. W pełnym przykładzie pokazujemy, jak zapisać ten token w pamięci lokalnej przeglądarki i pobrać go podczas wysyłania żądania do interfejsu API.

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) {
  console.log(xhr.response);
};
xhr.send(null);

Pełny przykład

Punkty końcowe OAuth 2.0

Ten przykładowy kod pokazuje, jak przeprowadzić procedurę OAuth 2.0 w JavaScript bez używania biblioteki klienta interfejsów Google API w JavaScript. Kod dotyczy strony HTML, na której wyświetla się przycisk umożliwiający wypróbowanie żądania do interfejsu API. Gdy klikniesz przycisk, kod sprawdzi, czy strona zapisała token dostępu do interfejsu API w pamięci lokalnej przeglądarki. Jeśli tak, wykonuje żądanie interfejsu API. W przeciwnym razie rozpocznie przepływ OAuth 2.0.

W przypadku przepływu OAuth 2.0 strona wykonuje te czynności:

  1. Kieruje użytkownika na serwer OAuth 2.0 Google, który prosi o dostęp do zakresów https://www.googleapis.com/auth/drive.metadata.readonlyhttps://www.googleapis.com/auth/calendar.readonly.
  2. Po przyznaniu (lub odmowie) dostępu do co najmniej jednego zakresu użytkownik zostanie przekierowany na pierwotną stronę, która przeanalizuje token dostępu z ciągu identyfikatora fragmentu.
  3. Na stronie sprawdzane są zakresy, do których użytkownik przyznał aplikacji dostęp.
  4. Jeśli użytkownik przyznał dostęp do żądanych zakresów, strona używa tokena dostępu do wysłania przykładowego żądania interfejsu API.

    Żądanie API wywołuje metodę about.get interfejsu Drive API, aby pobrać informacje o koncie Google Drive autoryzowanego użytkownika.

  5. Jeśli żądanie zostanie wykonane, odpowiedź interfejsu API zostanie zarejestrowana w konsoli debugowania przeglądarki.

Dostęp do aplikacji możesz cofnąć na stronie Uprawnienia na swoim koncie Google. Aplikacja będzie widoczna jako OAuth 2.0 Demo for Google API Docs (wersja demonstracyjna OAuth 2.0 dla dokumentacji interfejsów API Google).

Aby uruchomić ten kod lokalnie, musisz ustawić wartości zmiennych YOUR_CLIENT_ID i YOUR_REDIRECT_URI, które odpowiadają Twoim danym uwierzytelniającym. Zmienna YOUR_REDIRECT_URI powinna być ustawiona na ten sam adres URL, pod którym wyświetla się strona. Wartość musi być dokładnie taka sama jak jeden z autoryzowanych identyfikatorów URI przekierowania dla klienta OAuth 2.0, który został skonfigurowany w . Jeśli ta wartość nie pasuje do autoryzowanego identyfikatora URI, pojawi się błąd redirect_uri_mismatch. W projekcie musi być też włączony odpowiedni interfejs API dla tego żądania.

<html><head></head><body>
<script>
  var YOUR_CLIENT_ID = 'REPLACE_THIS_VALUE';
  var YOUR_REDIRECT_URI = 'REPLACE_THIS_VALUE';

  // Parse query string to see if page request is coming from OAuth 2.0 server.
  var fragmentString = location.hash.substring(1);
  var params = {};
  var regex = /([^&=]+)=([^&]*)/g, m;
  while (m = regex.exec(fragmentString)) {
    params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
  }
  if (Object.keys(params).length > 0 && params['state']) {
    if (params['state'] == localStorage.getItem('state')) {
      localStorage.setItem('oauth2-test-params', JSON.stringify(params) );

      trySampleRequest();
    } else {
      console.log('State mismatch. Possible CSRF attack');
    }
  }

  // Function to generate a random state value
  function generateCryptoRandomState() {
    const randomValues = new Uint32Array(2);
    window.crypto.getRandomValues(randomValues);

    // Encode as UTF-8
    const utf8Encoder = new TextEncoder();
    const utf8Array = utf8Encoder.encode(
      String.fromCharCode.apply(null, randomValues)
    );

    // Base64 encode the UTF-8 data
    return btoa(String.fromCharCode.apply(null, utf8Array))
      .replace(/\+/g, '-')
      .replace(/\//g, '_')
      .replace(/=+$/, '');
  }

  // 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']) { 
      // User authorized the request. Now, check which scopes were granted.
      if (params['scope'].includes('https://www.googleapis.com/auth/drive.metadata.readonly')) {
        // User authorized read-only Drive activity permission.
        // Calling the APIs, etc.
        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 {
        // User didn't authorize read-only Drive activity permission.
        // Update UX and application accordingly
        console.log('User did not authorize read-only Drive activity permission.');
      }

      // Check if user authorized Calendar read permission.
      if (params['scope'].includes('https://www.googleapis.com/auth/calendar.readonly')) {
        // User authorized Calendar read permission.
        // Calling the APIs, etc.
        console.log('User authorized Calendar read permission.');
      }
      else {
        // User didn't authorize Calendar read permission.
        // Update UX and application accordingly
        console.log('User did not authorize Calendar read permission.');
      } 
    } else {
      oauth2SignIn();
    }
  }

  /*
   * Create form to request access token from Google's OAuth 2.0 server.
   */
  function oauth2SignIn() {
    // create random state value and store in local storage
    var state = generateCryptoRandomState();
    localStorage.setItem('state', state);

    // 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 https://www.googleapis.com/auth/calendar.readonly',
                  'state': state,
                  '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>

Reguły weryfikacji źródła JavaScript

Aby pomóc deweloperom w zapewnieniu bezpieczeństwa aplikacji, Google stosuje te reguły weryfikacji źródeł JavaScript: Pochodzenie JavaScriptu musi być zgodne z tymi regułami. Definicje domeny, hosta i schematu, o których mowa poniżej, znajdziesz w sekcji 3 dokumentu RFC 3986.

Reguły weryfikacji
Schemat

Pochodzenie JavaScriptu musi używać schematu HTTPS, a nie zwykłego protokołu HTTP. Identyfikatory URI hosta lokalnego (w tym identyfikatory URI adresów IP hosta lokalnego) są zwolnione z tej reguły.

Osoba prowadząca

Hosty nie mogą być surowymi adresami IP. Adresy IP hosta lokalnego są wyłączone z tej reguły.

Domena
  • Domeny najwyższego poziomu hosta (domeny najwyższego poziomu) muszą należeć do listy sufiksów publicznych.
  • Domeny hosta nie mogą być “googleusercontent.com”.
  • Źródła JavaScript nie mogą zawierać domen skracających adresy URL (np. goo.gl), chyba że aplikacja jest właścicielem domeny.
  • Userinfo

    Pochodzenie JavaScript nie może zawierać komponentu podrzędnego userinfo.

    Ścieżka

    Pochodzenie JavaScript nie może zawierać komponentu ścieżki.

    Zapytanie

    Pochodzenie JavaScript nie może zawierać komponentu zapytania.

    Fragment

    Pochodzenie JavaScript nie może zawierać komponentu fragmentu.

    Znaki Punkty początkowe JavaScript nie mogą zawierać niektórych znaków, w tym:
    • Symbole wieloznaczne ('*')
    • Znaki ASCII, których nie można wydrukować
    • Nieprawidłowe kodowanie z użyciem znaków procentów (każde kodowanie z użyciem znaków procentów, które nie jest zgodne z formatem kodowania URL, czyli znaku procentu, po którym następują 2 cyfry szesnastkowe)
    • znaki puste (zakodowany znak NULL, np. %00, %C0%80)

    Autoryzacja przyrostowa

    W protokole OAuth 2.0 aplikacja prosi o autoryzację dostępu do zasobów, które są identyfikowane przez zakresy. Sprawdzoną metodą zapewniającą komfort użytkownikom jest proszenie o autoryzację dostępu do zasobów w momencie, gdy są one potrzebne. Aby to umożliwić, serwer autoryzacji Google obsługuje autoryzację przyrostową. Ta funkcja umożliwia wysyłanie żądań zakresów w miarę potrzeb. Jeśli użytkownik przyzna uprawnienia do nowego zakresu, zwracany jest kod autoryzacji, który można wymienić na token zawierający wszystkie zakresy, do których użytkownik przyznał uprawnienia w projekcie.

    Na przykład aplikacja, która umożliwia użytkownikom odsłuchiwanie utworów muzycznych i tworzenie miksów, może potrzebować bardzo niewielu zasobów podczas logowania – być może tylko nazwy osoby logującej się. Zapisanie ukończonego miksu będzie jednak wymagało dostępu do Dysku Google. Większość użytkowników uznałaby za naturalne, gdyby prośba o dostęp do Dysku Google pojawiała się tylko wtedy, gdy aplikacja faktycznie go potrzebuje.

    W tym przypadku podczas logowania aplikacja może poprosić o zakresy openidprofile, aby przeprowadzić podstawowe logowanie, a później, podczas pierwszego żądania zapisu miksu, poprosić o zakres https://www.googleapis.com/auth/drive.file.

    W przypadku tokena dostępu uzyskanego w ramach autoryzacji przyrostowej obowiązują te reguły:

    • Tokena można używać do uzyskiwania dostępu do zasobów odpowiadających dowolnemu z zakresów włączonych do nowego, połączonego upoważnienia.
    • Gdy używasz tokena odświeżania do uzyskania tokena dostępu w przypadku autoryzacji łączonej, token dostępu reprezentuje autoryzację łączoną i może być używany w przypadku dowolnej z wartości scope uwzględnionych w odpowiedzi.
    • Łączna autoryzacja obejmuje wszystkie zakresy, które użytkownik przyznał projektowi interfejsu API, nawet jeśli przyznanie zostało zainicjowane przez różnych klientów. Jeśli na przykład użytkownik przyzna dostęp do jednego zakresu za pomocą klienta aplikacji na komputery, a następnie przyzna inny zakres tej samej aplikacji za pomocą klienta mobilnego, połączone uprawnienia będą obejmować oba zakresy.
    • Jeśli cofniesz token reprezentujący połączoną autoryzację, dostęp do wszystkich zakresów autoryzacji w imieniu powiązanego użytkownika zostanie cofnięty jednocześnie.

    Poniższe przykłady kodu pokazują, jak dodać zakresy do dotychczasowego tokena dostępu. Dzięki temu aplikacja nie musi zarządzać wieloma tokenami dostępu.

    Punkty końcowe OAuth 2.0

    Aby dodać zakresy do istniejącego tokena dostępu, w żądaniu wysyłanym do serwera OAuth 2.0 Google uwzględnij parametr include_granted_scopes.

    Poniższy fragment kodu pokazuje, jak to zrobić. Fragment kodu zakłada, że zakresy, dla których ważny jest token dostępu, są przechowywane w pamięci lokalnej przeglądarki. (Kod pełnego przykładu przechowuje listę zakresów, dla których token dostępu jest ważny, ustawiając właściwość oauth2-test-params.scope w pamięci lokalnej przeglądarki).

    Fragment kodu porównuje zakresy, dla których token dostępu jest ważny, z zakresem, którego chcesz użyć w przypadku konkretnego zapytania. Jeśli token dostępu nie obejmuje tego zakresu, rozpoczyna się przepływ OAuth 2.0. Funkcja oauth2SignIn jest taka sama jak ta podana w kroku 2 (i w pełnym przykładzie).

    var SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly';
    var params = JSON.parse(localStorage.getItem('oauth2-test-params'));
    
    var current_scope_granted = false;
    if (params.hasOwnProperty('scope')) {
      var scopes = params['scope'].split(' ');
      for (var s = 0; s < scopes.length; s++) {
        if (SCOPE == scopes[s]) {
          current_scope_granted = true;
        }
      }
    }
    
    if (!current_scope_granted) {
      oauth2SignIn(); // This function is defined elsewhere in this document.
    } else {
      // Since you already have access, you can proceed with the API request.
    }

    Unieważnienie tokena

    W niektórych przypadkach użytkownik może chcieć cofnąć dostęp przyznany aplikacji. Użytkownik może cofnąć dostęp, otwierając Ustawienia konta. Więcej informacji znajdziesz w sekcji Usuwanie dostępu witryny lub aplikacji w artykule pomocy Strony internetowe i aplikacje innych firm z dostępem do Twojego konta.

    Aplikacja może też programowo unieważnić przyznany jej dostęp. Programowe wycofywanie jest ważne w przypadkach, gdy użytkownik rezygnuje z subskrypcji, usuwa aplikację lub zasoby interfejsu API wymagane przez aplikację uległy znacznym zmianom. Innymi słowy, część procesu usuwania może obejmować żądanie interfejsu API, aby upewnić się, że uprawnienia przyznane wcześniej aplikacji zostały usunięte.

    Punkty końcowe OAuth 2.0

    Aby programowo unieważnić token, aplikacja wysyła żądanie do https://oauth2.googleapis.com/revoke i dołącza token jako parametr:

    curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \
            https://oauth2.googleapis.com/revoke?token={token}

    Może to być token dostępu lub token odświeżania. Jeśli token jest tokenem dostępu i ma odpowiedni token odświeżania, token odświeżania również zostanie unieważniony.

    Jeśli wycofanie zostanie przetworzone, kod stanu HTTP odpowiedzi to 200. W przypadku błędów zwracany jest kod stanu HTTP 400 wraz z kodem błędu.

    Poniższy fragment kodu JavaScript pokazuje, jak cofnąć token w JavaScripcie bez użycia biblioteki klienta interfejsów Google API w JavaScripcie. Punkt końcowy Google OAuth 2.0 do odwoływania tokenów nie obsługuje udostępniania zasobów między domenami (CORS), więc kod tworzy formularz i przesyła go do punktu końcowego zamiast używać metody XMLHttpRequest() do wysyłania żądania.

    function revokeAccess(accessToken) {
      // Google's OAuth 2.0 endpoint for revoking access tokens.
      var revokeTokenEndpoint = 'https://oauth2.googleapis.com/revoke';
    
      // Create <form> element to use to POST data to the OAuth 2.0 endpoint.
      var form = document.createElement('form');
      form.setAttribute('method', 'post');
      form.setAttribute('action', revokeTokenEndpoint);
    
      // Add access token to the form so it is set as value of 'token' parameter.
      // This corresponds to the sample curl request, where the URL is:
      //      https://oauth2.googleapis.com/revoke?token={token}
      var tokenField = document.createElement('input');
      tokenField.setAttribute('type', 'hidden');
      tokenField.setAttribute('name', 'token');
      tokenField.setAttribute('value', accessToken);
      form.appendChild(tokenField);
    
      // Add form to page and submit it to actually revoke the token.
      document.body.appendChild(form);
      form.submit();
    }

    Wdrażanie Ochrony wszystkich kont

    Dodatkowym krokiem, który należy podjąć w celu ochrony kont użytkowników, jest wdrożenie ochrony międzykontowej za pomocą usługi ochrony międzykontowej Google. Ta usługa umożliwia subskrybowanie powiadomień o zdarzeniach związanych z bezpieczeństwem, które dostarczają aplikacji informacji o ważnych zmianach na koncie użytkownika. Na podstawie tych informacji możesz podejmować działania w zależności od tego, jak chcesz reagować na zdarzenia.

    Oto kilka przykładów typów zdarzeń wysyłanych do Twojej aplikacji przez usługę ochrony kont Google:

    • https://schemas.openid.net/secevent/risc/event-type/sessions-revoked
    • https://schemas.openid.net/secevent/oauth/event-type/token-revoked
    • https://schemas.openid.net/secevent/risc/event-type/account-disabled

    Więcej informacji o wdrażaniu ochrony wszystkich kont i pełną listę dostępnych zdarzeń znajdziesz na stronie Ochrona kont użytkowników za pomocą ochrony wszystkich kont .