Como usar o modelo de token

A biblioteca JavaScript google.accounts.oauth2 ajuda 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 permissão implícita do OAuth 2.0 e foi projetado para permitir que você chame as APIs do Google diretamente usando REST e CORS ou para usar nossa biblioteca de cliente das 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 dados de usuários protegidos em um navegador, os usuários no seu site acionam o seletor de contas, o login e os processos de consentimento baseados na Web do Google. Por fim, os servidores OAuth do Google emitem e retornam um token de acesso ao seu app da Web.

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

Recomendamos que você siga a abordagem descrita aqui em vez das técnicas abordadas no guia OAuth 2.0 para aplicativos da Web do lado do cliente anterior.

Configuração

Encontre ou crie um ID do cliente seguindo as etapas descritas no guia Criar credenciais de ID do cliente da API do Google. Em seguida, adicione a biblioteca de cliente às páginas do seu site que vão chamar as APIs do Google. Por fim, inicialize o cliente do token. Isso geralmente é 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 de cliente do seu app da Web. Opcionalmente, você pode 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:

  • Escolha a conta,
  • fazer login na Conta do Google,
  • conceda consentimento para que o app da Web acesse cada escopo solicitado.

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

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 para o gerenciador de callbacks.

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

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

A autorização incremental é uma política e uma metodologia de design de app usada para solicitar acesso a recursos, usando escopos, apenas conforme necessário, em vez de antecipadamente e todos de uma vez. Os usuários podem aprovar ou rejeitar o compartilhamento dos recursos individuais solicitados pelo app. Isso é conhecido como permissões granulares.

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

No entanto, há exceções. Os apps do Google Workspace Enterprise com delegação de autoridade em todo o domínio ou marcados como Confiáveis ignoram a tela de consentimento de permissões detalhadas. Para esses apps, os usuários não vão ver a tela de consentimento de permissão detalhada. Em vez disso, o app vai receber todos os escopos solicitados ou nenhum.

Para mais detalhes, consulte Como processar permissões granulares.

Autorização incremental

Para apps da Web, os dois cenários de alto nível a seguir demonstram a 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, os recursos são separados e gerenciados por página.

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

Ajax

Adicione suporte à autorização incremental ao seu app fazendo várias chamadas para requestAccessToken() e usando o parâmetro scope do objeto OverridableTokenClientConfig para solicitar escopos individuais no momento em que eles são 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 abrir uma seção de conteúdo recolhida.

App Ajax
Inicializar o cliente de 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 por 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'
             })
           );
        

Próximos eventos

Mostrar informações da agenda

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

Mostrar fotos

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

Cada chamada para requestAccessToken aciona um momento de consentimento do usuário. O app vai ter acesso apenas aos recursos necessários pela seção que o usuário escolher para abrir, limitando o compartilhamento de recursos pela escolha do usuário.

Várias páginas da Web

Ao projetar para a autorização incremental, várias páginas são usadas para solicitar apenas 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 extrair um token de acesso.

App com várias páginas
Página da Web Código
Página 1. Documentos para leitura
  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. Próximos eventos
  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 momento do carregamento. Nesse cenário, páginas da Web individuais são usadas para separar claramente a funcionalidade do usuário e os recursos por escopo. Em uma situação real, páginas individuais podem solicitar vários escopos relacionados.

Permissões granulares

As permissões granulares são processadas da mesma maneira em todos os cenários. Depois que requestAccessToken() invocar sua função de callback e um token de acesso for 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
        ...
      }
    }
  },
});

Todas as permissões aceitas anteriormente de sessões ou solicitações anteriores também serão incluídas na resposta. Um registro do 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 é necessário apenas na primeira vez que um usuário visita seu site e solicita um novo escopo, mas pode ser solicitado em cada carregamento de página usando 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 SO ou pelo navegador. Em vez disso, um novo token é recebido pela primeira vez no momento do carregamento da página ou, posteriormente, ao acionar uma chamada para requestAccessToken() por meio de um gesto do usuário, como pressionar 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 as APIs do Google usando REST e CORS. Isso permite que os usuários façam login, concedam consentimento, o Google emita um token de acesso e seu site trabalhe com os dados do usuário.

Neste exemplo, confira 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 o CORS para acessar APIs do Google para mais informações.

A próxima seção aborda como fazer a integração com APIs mais complexas com facilidade.

Como trabalhar com a biblioteca JavaScript das APIs do Google

O cliente de token funciona com a biblioteca de cliente da API do Google para JavaScript. Confira 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 uma vida útil curta. Se o token de acesso expirar antes do fim da sessão do usuário, receba um novo token chamando requestAccessToken() de um evento orientado pelo usuário, como um botão pressionado.

Chame o método google.accounts.oauth2.revoke para remover o consentimento do usuário e o acesso aos recursos de 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);
  });