A biblioteca JavaScript google.accounts.oauth2
ajuda você a pedir o consentimento do usuário e a receber um token de acesso para trabalhar com os dados dele. Ela se baseia no fluxo de concessão implícita do OAuth 2.0 e foi projetada para permitir que você chame as APIs do Google diretamente usando REST e CORS ou use a 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 dados protegidos do usuário em um navegador, os usuários do 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 baseada 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 mais antigo OAuth 2.0 para aplicativos da Web do lado do cliente.
Pré-requisitos
Siga as etapas descritas em Configuração para configurar a tela de permissão OAuth, conseguir um ID do cliente e carregar a 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. Inclua 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 token do OAuth 2.0
Use o método requestAccessToken()
para acionar o fluxo da UX do token e receber um
token de acesso. O Google pede que o usuário:
- Escolha a conta dela.
- fazer login na Conta do Google, caso ainda não tenha feito;
- conceder consentimento para que seu web app acesse cada escopo solicitado.
Um gesto do usuário aciona o fluxo de 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 seu manipulador de callback.
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.
Como lidar com o consentimento
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. Elas abordam o trabalho com vários escopos, quando e como lidar com o consentimento do usuário e muito mais.
A autorização incremental é uma política e uma metodologia de design de apps usadas para solicitar acesso a recursos, usando escopos, somente conforme necessário, em vez de antecipadamente e de uma só vez. Os usuários podem aprovar ou rejeitar o compartilhamento dos recursos individuais 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. 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 os escopos aprovados pelo usuário. Em seguida, 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 permissão granular. Para esses apps, os usuários não vão ver a tela de consentimento de permissão granular. Em vez disso, seu app vai receber todos os escopos solicitados ou nenhum.
Para mais informações, 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 considerações e metodologias de design, mas não são recomendações abrangentes sobre como criar consentimento no seu app. Os apps do mundo real podem usar uma variação ou combinação dessas técnicas.
Ajax
Adicione suporte para 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 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 de token no carregamento da página:
const client = google.accounts.oauth2.initTokenClient({ client_id: 'YOUR_GOOGLE_CLIENT_ID', callback: "onTokenResponse", }); Documentos para lerMostrar documentos recentes client.requestAccessToken( overrideConfig = ({ scope = 'https://www.googleapis.com/auth/documents.readonly' }) ); Próximos eventosMostrar informações da agenda client.requestAccessToken( overrideConfig = ({ scope = 'https://www.googleapis.com/auth/calendar.readonly' }) ); Carrossel de fotosMostrar 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 app terá acesso apenas aos recursos necessários para a seção que o usuário escolher abrir, 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 apenas os escopos necessários para carregar uma página, reduzindo a complexidade e a necessidade de fazer várias chamadas para obter o consentimento do usuário e recuperar um token de acesso.
App de várias páginas | ||||||||
---|---|---|---|---|---|---|---|---|
|
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, as 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, páginas individuais podem solicitar
vários escopos relacionados.
Permissões granulares
As permissões granulares são processadas da mesma forma em todos os cenários. Depois que
requestAccessToken()
invoca sua 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
...
}
}
},
});
Todas as concessõ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 só é necessário na primeira vez que ele visita seu site e solicita um novo escopo, mas pode ser solicitado em cada carregamento de página usando prompt=consent
em 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 navegador. Em vez disso, um novo token é obtido primeiro no momento do carregamento da página ou posteriormente ao acionar uma chamada para requestAccessToken()
por 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 às 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 mostra como fazer a integração com APIs mais complexas.
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, obtenha um novo token chamando requestAccessToken()
de um evento controlado pelo usuário, como o pressionamento de um botão.
Usar um token de acesso para revogar o consentimento
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 seu 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);
});