Korzystanie z modelu tokena

Biblioteka JavaScript google.accounts.oauth2 pomaga uzyskać zgodę użytkownika i pozyskać token dostępu do pracy z danymi użytkownika. Jest ono oparte na procesie domyślnego udzielania uprawnień w protokole OAuth 2.0 i ma na celu umożliwienie bezpośredniego wywoływania interfejsów API Google za pomocą protokołów REST i CORS lub korzystania z naszej biblioteki klienta interfejsów API Google na potrzeby JavaScriptu (znanej też jako gapi.client) w celu prostego i elastycznego uzyskiwania dostępu do bardziej złożonych interfejsów API.

Zanim użytkownicy uzyskają dostęp do chronionych danych w przeglądarce, muszą w Twojej witrynie uruchomić procesy wyboru konta, logowania się i wyrażania zgody w Google. Następnie serwery OAuth Google wydadzą token dostępu i przekażą go do Twojej aplikacji internetowej.

W przypadku modelu autoryzacji opartego na tokenach nie trzeba przechowywać na serwerze backendu tokenów odświeżania dla poszczególnych użytkowników.

Zalecamy stosowanie opisanej tutaj metody zamiast technik opisanych w starszym przewodniku OAuth 2.0 w przypadku aplikacji internetowych działających po stronie klienta.

Wymagania wstępne

Aby skonfigurować ekran zgody OAuth, uzyskać identyfikator klienta i wczytać bibliotekę klienta, wykonaj czynności opisane w sekcji Konfiguracja.

Inicjowanie klienta tokena

Wywołaj funkcję initTokenClient(), aby zainicjować nowego klienta tokena za pomocą identyfikatora klienta Twojej aplikacji internetowej. Opcjonalnie możesz podać listę co najmniej jednego zakresu, do którego użytkownik musi mieć dostęp:

const client = google.accounts.oauth2.initTokenClient({
  client_id: 'YOUR_GOOGLE_CLIENT_ID',
  scope: 'https://www.googleapis.com/auth/calendar.readonly',
  callback: (response) => {
    ...
  },
});

Uruchamianie procesu uzyskiwania tokena OAuth 2.0

Aby wywołać proces UX tokenu i uzyskać token dostępu, użyj metody requestAccessToken(). Google prosi użytkownika o:

  • Wybierz konto dziecka,
  • zalogować się na konto Google, jeśli nie jesteś jeszcze zalogowany(-a);
  • wyrazić zgodę na dostęp aplikacji internetowej do każdego żądanego zakresu.

Gest użytkownika uruchamia proces generowania tokena: <button onclick="client.requestAccessToken();">Authorize me</button>

Google zwróci wtedy do Twojego obsługiwana wywołania zwrotnego TokenResponse z tokenem dostępu i listą zakresów, do których użytkownik przyznał dostęp, lub błąd.

Użytkownicy mogą zamknąć okna wyboru konta lub logowania, w którym przypadku funkcja wywołania zwrotnego nie zostanie wywołana.

Projekt i wygodę aplikacji należy wdrożyć dopiero po dokładnym zapoznaniu się z zasadami OAuth 2.0 Google. Te zasady obejmują m.in. pracę z wieloma zakresami, sposób uzyskiwania zgody użytkownika i inne kwestie.

Autoryzacja cząstkowa to zasada i metodologia projektowania aplikacji służące do żądania dostępu do zasobów za pomocą zakresów tylko w miarę potrzeby, a nie od razu i jednocześnie. Użytkownicy mogą zaakceptować lub odrzucić udostępnianie poszczególnych zasobów, o które prosi aplikacja. Nazywa się to uprawnieniami szczegółowymi.

W trakcie tego procesu Google prosi o zgodę użytkownika, wymieniając poszczególne zakresy uprawnień, które mają być udostępnione aplikacji. Użytkownicy wybierają zasoby, które mają być udostępnione aplikacji. Następnie Google wywołuje Twoją funkcję wywołania zwrotnego, aby zwrócić token dostępu i zakresy zatwierdzone przez użytkownika. Aplikacja może bezpiecznie obsługiwać różne możliwe wyniki, korzystając z dokładnych uprawnień.

Są jednak wyjątki. Aplikacje Google Workspace Enterprise z upoważnieniem do działania w całej domenie lub oznaczone jako Zaufane pomijają ekran zgody na szczegółowe uprawnienia. W przypadku tych aplikacji użytkownicy nie zobaczą szczegółowego ekranu zgody na dostęp do danych. Zamiast tego aplikacja otrzyma wszystkie żądane zakresy uprawnień lub żadne.

Więcej informacji znajdziesz w artykule Zarządzanie szczegółowymi uprawnieniami.

Autoryzacja przyrostowa

W przypadku aplikacji internetowych te 2 ogólne scenariusze pokazują stopniowe udzielanie uprawnień za pomocą:

  • Jednostronna aplikacja Ajax, która często korzysta z biblioteki XMLHttpRequest i ma dynamiczny dostęp do zasobów.
  • Wiele stron internetowych, zasoby są rozdzielone i zarządzane na poziomie strony.

Te 2 scenariusze mają na celu zilustrowanie kwestii związanych z projektowaniem i metodologii, ale nie są wyczerpującymi zaleceniami dotyczącymi uzyskiwania zgody w aplikacji. W praktyce aplikacje mogą używać wariantu lub kombinacji tych technik.

Ajax

Dodaj do aplikacji obsługę stopniowego autoryzowania, wykonując kilka wywołań do requestAccessToken() i korzystając z parametru scope obiektu OverridableTokenClientConfig, aby żądać poszczególnych zakresów w chwili, gdy są potrzebne, i tylko wtedy, gdy jest to konieczne. W tym przykładzie zasoby będą żądane i widoczne tylko wtedy, gdy użytkownik rozwinie złożoną sekcję treści.

Aplikacja Ajax
Inicjalizacja klienta tokenów podczas wczytywania strony:
        const client = google.accounts.oauth2.initTokenClient({
          client_id: 'YOUR_GOOGLE_CLIENT_ID',
          callback: "onTokenResponse",
        });
      
Wyświetl prośbę o zgodę i pobierz tokeny dostępu za pomocą gestów użytkownika. Kliknij „+”, aby otworzyć:

Dokumenty do przeczytania

Pokaż ostatnie dokumenty

          client.requestAccessToken(
            overrideConfig = ({
               scope = 'https://www.googleapis.com/auth/documents.readonly'
             })
           );
        

Nadchodzące wydarzenia

Pokaż informacje o kalendarzu

          client.requestAccessToken(
            overrideConfig = ({
               scope = 'https://www.googleapis.com/auth/calendar.readonly'
             })
           );
        

Wyświetlanie zdjęć

          client.requestAccessToken(
            overrideConfig = ({
               scope = 'https://www.googleapis.com/auth/photoslibrary.readonly'
             })
           );
        

Każde wywołanie funkcji requestAccessToken powoduje wyświetlenie użytkownikowi prośby o zgodę. Aplikacja będzie mieć dostęp tylko do tych zasobów, które są wymagane w sekcji, którą użytkownik zdecyduje się rozwinąć. W ten sposób ograniczy się udostępnianie zasobów na podstawie wyboru użytkownika.

Wiele stron internetowych

Podczas projektowania autoryzacji stopniowej stosuje się wiele stron, aby żądać tylko zakresów wymaganych do wczytania strony. Dzięki temu zmniejsza się złożoność i konieczność wykonywania wielu wywołań w celu uzyskania zgody użytkownika i pobrania tokena dostępu.

Aplikacja wielostronicowa
Strona internetowa Kod
Strona 1. Dokumenty do przeczytania
  const client = google.accounts.oauth2.initTokenClient({
    client_id: 'YOUR_GOOGLE_CLIENT_ID',
    callback: "onTokenResponse",
    scope: 'https://www.googleapis.com/auth/documents.readonly',
  });
  client.requestAccessToken();
          
Strona 2. Nadchodzące wydarzenia
  const client = google.accounts.oauth2.initTokenClient({
    client_id: 'YOUR_GOOGLE_CLIENT_ID',
    callback: "onTokenResponse",
    scope: 'https://www.googleapis.com/auth/calendar.readonly',
  });
  client.requestAccessToken();
          
Strona 3. Karuzela zdjęć
  const client = google.accounts.oauth2.initTokenClient({
    client_id: 'YOUR_GOOGLE_CLIENT_ID',
    callback: "onTokenResponse",
    scope: 'https://www.googleapis.com/auth/photoslibrary.readonly',
  });
  client.requestAccessToken();
          

Każda strona prosi o wyznaczony zakres i uzyskiwanie tokena dostępu przez wywołanie funkcji initTokenClient()requestAccessToken() w momencie wczytywania. W tym scenariuszu poszczególne strony internetowe służą do wyraźnego oddzielenia funkcji i zasobów użytkowników według zakresu. W rzeczywistych sytuacjach poszczególne strony mogą wymagać wielu powiązanych zakresów.

Szczegółowe uprawnienia

Szczegółowe uprawnienia są obsługiwane w taki sam sposób we wszystkich scenariuszach. Gdy funkcja requestAccessToken() wywoła Twoją funkcję wywołania zwrotnego i zwróci token dostępu, sprawdź, czy użytkownik zatwierdził wymagane zakresy za pomocą funkcji hasGrantedAllScopes() lub hasGrantedAnyScope(). Na przykład:

const client = google.accounts.oauth2.initTokenClient({
  client_id: 'YOUR_GOOGLE_CLIENT_ID',
  scope: 'https://www.googleapis.com/auth/calendar.readonly \
          https://www.googleapis.com/auth/documents.readonly \
          https://www.googleapis.com/auth/photoslibrary.readonly',
  callback: (tokenResponse) => {
    if (tokenResponse && tokenResponse.access_token) {
      if (google.accounts.oauth2.hasGrantedAnyScope(tokenResponse,
          'https://www.googleapis.com/auth/photoslibrary.readonly')) {
        // Look at pictures
        ...
      }
      if (google.accounts.oauth2.hasGrantedAllScopes(tokenResponse,
          'https://www.googleapis.com/auth/calendar.readonly',
          'https://www.googleapis.com/auth/documents.readonly')) {
        // Meeting planning and review documents
        ...
      }
    }
  },
});

W odpowiedzi uwzględnione zostaną też wszystkie wcześniej zaakceptowane dotacje z poprzednich sesji lub prośby. Zapis zgody użytkownika jest przechowywany dla każdego użytkownika i identyfikatora klienta. Jest on zachowywany w przypadku wielu wywołań funkcji initTokenClient() lub requestAccessToken(). Domyślnie zgoda użytkownika jest wymagana tylko wtedy, gdy użytkownik po raz pierwszy odwiedza Twoją witrynę i prosi o nowy zakres, ale może być wymagana przy każdym wczytaniu strony za pomocą elementu prompt=consent w obiektach konfiguracji klienta tokena.

Praca z tokenami

W przypadku modelu tokenów token dostępu nie jest przechowywany przez system operacyjny ani przeglądarkę. Zamiast tego nowy token jest pobierany po raz pierwszy w momencie wczytywania strony lub później, gdy użytkownik wywoła funkcję requestAccessToken(), np. przez naciśnięcie przycisku.

Korzystanie z interfejsów API Google w ramach protokołu REST i zasobów wspólnych (CORS)

Token dostępu może służyć do wysyłania uwierzytelnionych żądań do interfejsów API Google za pomocą REST i CORS. Dzięki temu użytkownicy mogą się logować, wyrażać zgodę, a Google może wydawać tokeny dostępu, a Twoja witryna może pracować z danymi użytkownika.

W tym przykładzie wyświetla się nadchodzące wydarzenia w kalendarzu zalogowanego użytkownika przy użyciu tokena dostępu zwracanego przez funkcję tokenRequest():

var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://www.googleapis.com/calendar/v3/calendars/primary/events');
xhr.setRequestHeader('Authorization', 'Bearer ' + tokenResponse.access_token);
xhr.send();

Więcej informacji znajdziesz w artykule Jak używać CORS do uzyskiwania dostępu do interfejsów API Google.

W następnej sekcji dowiesz się, jak łatwo integrować się z bardziej złożonymi interfejsami API.

Praca z biblioteką JavaScript interfejsów API Google

Klient tokenu współpracuje z biblioteką klienta interfejsu API Google dla języka JavaScript. Zobacz fragment kodu poniżej.

const client = google.accounts.oauth2.initTokenClient({
  client_id: 'YOUR_GOOGLE_CLIENT_ID',
  scope: 'https://www.googleapis.com/auth/calendar.readonly',
  callback: (tokenResponse) => {
    if (tokenResponse && tokenResponse.access_token) {
      gapi.client.setApiKey('YOUR_API_KEY');
      gapi.client.load('calendar', 'v3', listUpcomingEvents);
    }
  },
});

function listUpcomingEvents() {
  gapi.client.calendar.events.list(...);
}

Wygaśnięcie tokenu

Zgodnie z ich projektem tokeny dostępu mają krótki okres ważności. Jeśli token dostępu wygaśnie przed zakończeniem sesji użytkownika, pobierz nowy token, wywołując funkcję requestAccessToken() z zdarzenia wywołanego przez użytkownika, np. naciśnięcia przycisku.

Aby cofnąć zgodę użytkownika i dostęp do zasobów we wszystkich zakresach przyznanych aplikacji, wywołaj metodę google.accounts.oauth2.revoke. Aby cofnąć to uprawnienie, musisz mieć ważny token dostępu:

google.accounts.oauth2.revoke('414a76cb127a7ece7ee4bf287602ca2b56f8fcbf7fcecc2cd4e0509268120bd7', done => {
    console.log(done);
    console.log(done.successful);
    console.log(done.error);
    console.log(done.error_description);
  });