Como usar o modelo de token

A biblioteca JavaScript google.accounts.oauth2 ajuda você a solicitar o consentimento do usuário e receber um token de acesso para trabalhar com os dados do usuário. Ele é baseado no fluxo de concessão implícita do OAuth 2.0 e projetado para permitir que você chame APIs do Google diretamente usando REST e CORS ou use nossa biblioteca de cliente de APIs do Google para JavaScript (também conhecida como gapi.client) para acesso simples e flexível às nossas APIs mais complexas.

Antes de acessar os dados protegidos do usuário em um navegador, os usuários no seu site acionam os processos de escolha, login e consentimento da conta baseados na Web do Google e, por último, os servidores OAuth do Google emitem e retornam um token de acesso ao seu app da Web.

No modelo de autorização baseado em tokens, não é necessário armazenar tokens de atualização por usuário no seu servidor de back-end.

É recomendável que você siga a abordagem descrita aqui em vez das técnicas cobertas pelo antigo guia OAuth 2.0 para aplicativos da Web do lado do cliente.

Configuração

Para encontrar ou criar um ID do cliente, siga as etapas descritas no guia Acessar o ID do cliente da API do Google. Em seguida, adicione a biblioteca de cliente às páginas do seu site que chamarão as APIs do Google. Por último, inicialize o cliente de token. Normalmente, isso é feito no gerenciador onload da biblioteca de cliente.

Inicializar um cliente de token

Chame initTokenClient() para inicializar um novo cliente de token com o ID do cliente do seu app da Web. Opcionalmente, é possível incluir uma lista de um ou mais escopos que o usuário precisa acessar:

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

Acionar o fluxo de tokens do OAuth 2.0

Use o método requestAccessToken() para acionar o fluxo de UX do token e receber um token de acesso. O Google solicita que o usuário:

  • escolher a conta dele;
  • fazer login na Conta do Google, se ainda não tiver feito login;
  • permitir que seu app da Web acesse cada escopo solicitado.

Um gesto do usuário aciona o fluxo do token: <button onclick="client.requestAccessToken();">Authorize me</button>

Em seguida, o Google retorna um TokenResponse contendo um token de acesso e uma lista de escopos a que o usuário concedeu acesso ou um erro ao gerenciador de callback.

Os usuários podem fechar o seletor de contas ou as janelas de login. Nesse caso, a função de callback não será invocada.

O design e a experiência do usuário do seu app só devem ser implementados após uma análise completa das Políticas do OAuth 2.0 do Google. Essas políticas abrangem o trabalho com vários escopos, quando e como lidar com o consentimento do usuário e muito mais.

A autorização incremental é uma metodologia de política e design de apps usada para solicitar acesso a recursos usando escopos, somente quando necessário, em vez de antecipado e de uma só vez. Os usuários podem aprovar ou rejeitar o compartilhamento dos recursos específicos solicitados pelo app, o que é conhecido como permissões granulares.

Durante esse processo, o Google solicita o consentimento do usuário, listando individualmente cada escopo solicitado. Em seguida, os usuários selecionam os recursos a serem compartilhados com o app e, por fim, o Google invoca sua função de callback para retornar um token de acesso e escopos aprovados pelo usuário. Em seguida, o app processa com segurança os vários resultados possíveis com permissões granulares.

Autorização incremental

Para apps da Web, os dois cenários de alto nível a seguir demonstram autorização incremental usando:

  • Um app Ajax de página única, geralmente usando XMLHttpRequest com acesso dinâmico a recursos.
  • Várias páginas da Web, recursos são separados e gerenciados em cada página.

Esses dois cenários são apresentados para ilustrar considerações e metodologias de design, mas não são recomendações abrangentes sobre como solicitar consentimento ao app. Apps reais podem usar uma variação ou combinação dessas técnicas.

Ajax

Adicione suporte à autorização incremental para o app fazendo várias chamadas para requestAccessToken() e usando o parâmetro scope do objeto OverridableTokenClientConfig para solicitar escopos individuais no momento em que forem necessários e somente quando necessário. Neste exemplo, os recursos serão solicitados e ficarão visíveis somente depois que um gesto do usuário expandir uma seção de conteúdo recolhida.

App Ajax
Inicialize o cliente do token no carregamento da página:
        const client = google.accounts.oauth2.initTokenClient({
          client_id: 'YOUR_GOOGLE_CLIENT_ID',
          callback: "onTokenResponse",
        });
      
Solicite consentimento e receba tokens de acesso usando gestos do usuário. Clique em "+" para abrir:

Documentos para ler

Mostrar documentos recentes

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

Eventos futuros

Mostrar informações da agenda

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

Exibir fotos

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

Cada chamada para requestAccessToken aciona um momento de consentimento do usuário. Seu aplicativo terá acesso apenas aos recursos exigidos pela seção que o usuário escolhe para expandir, limitando o compartilhamento de recursos pela escolha do usuário.

Várias páginas da Web

Ao projetar para autorização incremental, várias páginas são usadas para solicitar somente os escopos necessários para carregar uma página, reduzindo a complexidade e a necessidade de fazer várias chamadas para receber o consentimento do usuário e recuperar um token de acesso.

App de várias páginas
Página da Web Código
Página 1. Documentos para ler
  const client = google.accounts.oauth2.initTokenClient({
    client_id: 'YOUR_GOOGLE_CLIENT_ID',
    callback: "onTokenResponse",
    scope: 'https://www.googleapis.com/auth/documents.readonly',
  });
  client.requestAccessToken();
          
Página 2. Eventos futuros
  const client = google.accounts.oauth2.initTokenClient({
    client_id: 'YOUR_GOOGLE_CLIENT_ID',
    callback: "onTokenResponse",
    scope: 'https://www.googleapis.com/auth/calendar.readonly',
  });
  client.requestAccessToken();
          
Página 3. Carrossel de fotos
  const client = google.accounts.oauth2.initTokenClient({
    client_id: 'YOUR_GOOGLE_CLIENT_ID',
    callback: "onTokenResponse",
    scope: 'https://www.googleapis.com/auth/photoslibrary.readonly',
  });
  client.requestAccessToken();
          

Cada página solicita o escopo necessário e recebe um token de acesso chamando initTokenClient() e requestAccessToken() no tempo de carregamento. Nesse cenário, páginas da Web individuais são usadas para separar claramente a funcionalidade e os recursos do usuário por escopo. Em uma situação real, as páginas individuais podem solicitar vários escopos relacionados.

Permissões granulares

As permissões granulares são tratadas da mesma forma em todos os cenários. Depois que requestAccessToken() invocar a função de callback e um token de acesso retornado, verifique se o usuário aprovou os escopos solicitados usando hasGrantedAllScopes() ou hasGrantedAnyScope(). Exemplo:

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
        ...
      }
    }
  },
});

As concessões aceitas anteriormente de sessões ou solicitações anteriores também serão incluídas na resposta. Um registro de consentimento do usuário é mantido por usuário e ID do cliente e persiste em várias chamadas para initTokenClient() ou requestAccessToken(). Por padrão, o consentimento do usuário só é necessário na primeira vez que ele acessa seu site e solicita um novo escopo, mas pode ser solicitado em cada carregamento de página usando o prompt=consent nos objetos de configuração do cliente de token.

Como trabalhar com tokens

No modelo de token, um token de acesso não é armazenado pelo sistema operacional ou navegador, em vez disso, um novo token é obtido primeiro no momento do carregamento da página ou, posteriormente, acionando uma chamada para requestAccessToken() usando um gesto do usuário, como o pressionamento de um botão.

Como usar REST e CORS com as APIs do Google

Um token de acesso pode ser usado para fazer solicitações autenticadas para APIs do Google usando REST e CORS. Isso permite que os usuários façam login e deem consentimento, com o Google para emitir um token de acesso e para que seu site trabalhe com os dados do usuário.

Neste exemplo, veja os próximos eventos da agenda dos usuários conectados usando o token de acesso retornado por 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();

Consulte Como usar CORS para acessar as APIs do Google.

A próxima seção explica como fazer uma integração fácil com APIs mais complexas.

Como trabalhar com a biblioteca de APIs do Google JavaScript

O cliente do token funciona com a Biblioteca de cliente da API do Google para JavaScript. Veja o snippet de código abaixo.

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(...);
}

Expiração do token

Por padrão, os tokens de acesso têm um ciclo de vida curto. Se o token de acesso expirar antes do fim da sessão do usuário, consiga um novo token chamando requestAccessToken() em um evento acionado pelo usuário, como o pressionamento de um botão.

Chame o método google.accounts.oauth2.revoke para remover o consentimento do usuário e o acesso a recursos para todos os escopos concedidos ao app. Um token de acesso válido é necessário para revogar essa permissão:

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