Korzystanie z modelu tokena

Biblioteka JavaScript google.accounts.oauth2 ułatwia wyświetlanie próśb o zgodę użytkownika i uzyskiwanie tokena dostępu do obsługi danych użytkownika. Jest oparty na procesie ukrycia uwierzytelniania OAuth 2.0 i zaprojektowany tak, aby umożliwiać bezpośrednie wywoływanie interfejsów API Google za pomocą REST i CORS lub korzystanie z naszej biblioteki klienta interfejsów API Google dla języka JavaScript (znanej też jako gapi.client) w celu uzyskania prostego i elastycznego dostępu do bardziej złożonych interfejsów API.

Przed uzyskaniem w przeglądarce chronionych danych użytkownika użytkownicy w Twojej witrynie uruchamiają internetowe procesy wyboru konta, logowania i uzyskiwania zgody, a na koniec – problem z serwerami OAuth Google – i zwraca token dostępu do Twojej aplikacji internetowej.

W modelu autoryzacji opartym na tokenach nie ma potrzeby przechowywania na serwerze backendu tokenów odświeżania dla poszczególnych użytkowników.

Zalecamy stosowanie opisanego tutaj podejścia, a nie metod opisanych w starszym przewodniku protokołu OAuth 2.0 dla aplikacji internetowych po stronie klienta.

Konfiguracja

Znajdź lub utwórz identyfikator klienta, wykonując czynności opisane w przewodniku Uzyskiwanie identyfikatora klienta interfejsu API Google. Następnie dodaj bibliotekę klienta do stron w witrynie, które będą wywoływać interfejsy API Google. Na koniec zainicjuj klienta tokenów. Zwykle odbywa się to w ramach modułu obsługi onload biblioteki klienta.

Inicjowanie klienta tokena

Wywołaj initTokenClient(), aby zainicjować nowego klienta tokena za pomocą identyfikatora klienta Twojej aplikacji internetowej. Opcjonalnie możesz dodać listę zakresów, do których użytkownik potrzebuje dostępu:

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

Wyzwalanie przepływu tokenów OAuth 2.0

Użyj metody requestAccessToken(), aby aktywować przepływ UX tokena i uzyskać token dostępu. Google prosi użytkownika o wykonanie tych czynności:

  • Wybierz konto użytkownika,
  • zaloguj się na konto Google,
  • zezwól aplikacji internetowej na dostęp do każdego żądanego zakresu.

Gest użytkownika wyzwala przepływ tokena: <button onclick="client.requestAccessToken();">Authorize me</button>

Następnie Google zwraca modułowi obsługi wywołania zwrotnego obiekt TokenResponse zawierający token dostępu i listę zakresów, do których użytkownik przyznał dostęp, lub błąd.

Użytkownicy mogą zamknąć okno wyboru konta lub okna logowania. W takim przypadku funkcja wywołania zwrotnego nie zostanie wywołana.

Projekt i wygoda użytkowników Twojej aplikacji powinny zostać wdrożone dopiero po dokładnym zapoznaniu się z zasadami Google dotyczącymi protokołu OAuth 2.0. Zasady te obejmują m.in. pracę z wieloma zakresami oraz czas i sposób obsługi zgody użytkownika.

Autoryzacja przyrostowa to metodologia tworzenia zasad i projektowania aplikacji używana do wysyłania próśb o dostęp do zasobów przy użyciu zakresów tylko w razie potrzeby, a nie od razu i w całości. Użytkownicy mogą zatwierdzać lub odrzucać poszczególne zasoby, o które prosi aplikacja. Są to tzw. szczegółowe uprawnienia.

W trakcie tego procesu Google prosi o zgodę użytkownika, indywidualnie wyświetlając listę poszczególnych żądanych zakresów, a następnie wybiera zasoby, które mają zostać udostępnione aplikacji. Na koniec Google wywołuje funkcję wywołania zwrotnego, aby zwrócić token dostępu i zakresy zatwierdzone przez użytkownika. Aplikacja bezpiecznie obsługuje różne możliwe wyniki dzięki szczegółowym uprawnieniom.

Autoryzacja przyrostowa

W przypadku aplikacji internetowych te 2 ogólne scenariusze pokazują przyrostową autoryzację przy użyciu:

  • Jednostronicowa aplikacja Ajax, często korzystająca z XMLHttpRequest z dynamicznym dostępem do zasobów.
  • Wiele stron internetowych, zasoby są rozdzielane i zarządzane na poziomie każdej strony

Te 2 scenariusze mają za zadanie zilustrować kwestie i metodologie związane z projektowaniem, ale nie są wyczerpującymi zaleceniami dotyczącymi uzyskiwania zgody użytkowników w aplikacji. Rzeczywiste aplikacje mogą wykorzystywać odmianę lub połączenie tych technik.

Ajax

Dodaj obsługę autoryzacji przyrostowej do swojej aplikacji, wykonując wiele wywołań funkcji requestAccessToken() i używając parametru scope obiektu OverridableTokenClientConfig, aby żądać poszczególnych zakresów w momencie i tylko w razie potrzeby. W tym przykładzie zasoby będą żądane i widoczne dopiero po tym, jak gest użytkownika rozwinie zwiniętą sekcję treści.

Aplikacja Ajax
Zainicjuj klienta tokena podczas wczytywania strony:
        const client = google.accounts.oauth2.initTokenClient({
          client_id: 'YOUR_GOOGLE_CLIENT_ID',
          callback: "onTokenResponse",
        });
      
Poproś o zgodę i uzyskaj tokeny dostępu za pomocą gestów. 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 z kalendarza

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

Wyświetl zdjęcia

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

Każde wywołanie funkcji requestAccessToken uruchamia moment wyrażenia zgody przez użytkownika. Twoja aplikacja ma dostęp tylko do tych zasobów, które są wymagane przez sekcję wybraną przez użytkownika do rozwinięcia, co ogranicza możliwość udostępniania zasobów przez wybór użytkownika.

Wiele stron internetowych

W przypadku autoryzacji przyrostowej wiele stron służy do żądania tylko tych zakresów wymaganych do wczytania strony. Dzięki temu nie trzeba wywoływać 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 żąda wymaganego zakresu i uzyskiwała token dostępu, wywołując initTokenClient() i requestAccessToken() podczas wczytywania. W tym scenariuszu poszczególne strony internetowe służą do wyraźnego odseparowania funkcji i zasobów użytkowników w zależności od zakresu. W świecie rzeczywistym poszczególne strony mogą żądać wielu powiązanych zakresów.

Szczegółowe uprawnienia

Szczegółowe uprawnienia są obsługiwane w ten sam sposób we wszystkich scenariuszach. Gdy requestAccessToken() wywoła funkcję wywołania zwrotnego i zwróci token dostępu, sprawdź, czy użytkownik zatwierdził żądane zakresy za pomocą 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
        ...
      }
    }
  },
});

Wszelkie wcześniej zaakceptowane prośby i uprawnienia z poprzednich sesji lub próśb też zostaną uwzględnione w odpowiedzi. Rejestr zgody użytkownika jest przechowywany dla każdego użytkownika i identyfikatora klienta i zachowuje ważność 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 żąda nowego zakresu. Może być jednak wymagana przy każdym wczytaniu strony za pomocą metody prompt=consent w obiektach konfiguracji klienta tokena.

Praca z tokenami

W modelu tokenu token dostępu nie jest przechowywany przez system operacyjny ani przez przeglądarkę. Nowy token jest generowany najpierw podczas wczytywania strony, a potem przez wywołanie wywołania requestAccessToken() za pomocą gestu użytkownika, takiego jak naciśnięcie przycisku.

Używanie REST i CORS z interfejsami API Google

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 będą mogli się zalogować, udzielić zgody, wystawić przez Google token dostępu, a Twoja witryna będzie pracować z danymi użytkownika.

W tym przykładzie wyświetl nadchodzące wydarzenia w kalendarzu zalogowanych użytkowników za pomocą tokena dostępu zwróconego przez 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 za pomocą CORS uzyskać dostęp do interfejsów API Google.

W następnej sekcji opisujemy, jak łatwo przeprowadzić integrację z bardziej złożonymi interfejsami API.

Praca z biblioteką JavaScript interfejsów API Google

Klient tokena 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 tokena

Z założenia tokeny dostępu są ważne przez krótki czas. Jeśli token dostępu wygaśnie przed końcem sesji użytkownika, uzyskaj nowy token, wywołując requestAccessToken() ze zdarzenia wywołanego przez użytkownika, np. naciśnięcia przycisku.

Wywołaj metodę google.accounts.oauth2.revoke, aby cofnąć zgodę użytkownika i dostęp do zasobów we wszystkich zakresach przyznanych Twojej aplikacji. Aby można było cofnąć te uprawnienia, wymagany jest prawidłowy 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);
  });