OAuth 2.0: autenticar usuários com o Google

O OAuth2 é o protocolo padrão do setor para autorização. Ele oferece um mecanismo para que os usuários concedam acesso a informações particulares a aplicativos da Web e para computador sem compartilhar o nome de usuário, a senha e outras credenciais particulares.

Este tutorial cria uma extensão que acessa os contatos do Google de um usuário usando a API Google People e a API Chrome Identity. Como as extensões não são carregadas pelo HTTPS e não podem fazer redirecionamentos ou definir cookies, elas dependem da API Chrome Identity para usar o OAuth2.

Primeiros passos

Comece criando um diretório e os seguintes arquivos iniciais.

manifest.json

Adicione o manifesto criando um arquivo chamado manifest.json e incluindo o seguinte código.

{
  "name": "OAuth Tutorial FriendBlock",
  "version": "1.0",
  "description": "Uses OAuth to connect to Google's People API and display contacts photos.",
  "manifest_version": 3,
  "action": {
    "default_title": "FriendBlock, friends face's in a block."
  },
  "background": {
    "service_worker": "service-worker.js"
  }
}

service-worker.js

Adicione o worker de serviço da extensão criando um arquivo chamado service-worker.js e incluindo o seguinte código.

chrome.action.onClicked.addListener(function() {
  chrome.tabs.create({url: 'index.html'});
});

index.html

Adicione um arquivo HTML chamado index.html e inclua o seguinte código.

<html>
  <head>
    <title>FriendBlock</title>
    <style>
      button {
        padding: 10px;
        background-color: #3C79F8;
        display: inline-block;
      }
    </style>
  </head>
  <body>
    <button>FriendBlock Contacts</button>
    <div id="friendDiv"></div>
  </body>
</html>

Manter um ID de extensão consistente

Preservar um único ID é essencial durante o desenvolvimento. Para manter um ID consistente, siga estas etapas:

Fazer upload da extensão no painel de controle do desenvolvedor

Empacote o diretório da extensão em um arquivo .zip e faça upload dele no Painel do desenvolvedor do Chrome sem publicá-lo:

  1. No Painel do desenvolvedor, clique em Adicionar novo item.
  2. Clique em Procurar arquivos, selecione o arquivo zip da extensão e faça upload dele.
  3. Acesse a guia Package e clique em View public key.
Botão &quot;Ver chave pública&quot; na guia &quot;Pacote&quot;
Botão "View public key" na guia "Package"

Quando a caixa de diálogo estiver aberta, siga estas etapas:

  1. Copie o código entre -----BEGIN PUBLIC KEY----- e -----END PUBLIC KEY-----.
  2. Remova as quebras de linha para criar uma única linha de texto.
Janela de diálogo de chave pública
Janela de diálogo da chave pública

Adicione o código ao manifest.json no campo "key". Dessa forma, a extensão vai usar o mesmo ID.

{ // manifest.json
  "manifest_version": 3,
...
  "key": "ThisKeyIsGoingToBeVeryLong/go8GGC2u3UD9WI3MkmBgyiDPP2OreImEQhPvwpliioUMJmERZK3zPAx72z8MDvGp7Fx7ZlzuZpL4yyp4zXBI+MUhFGoqEh32oYnm4qkS4JpjWva5Ktn4YpAWxd4pSCVs8I4MZms20+yx5OlnlmWQEwQiiIwPPwG1e1jRw0Ak5duPpE3uysVGZXkGhC5FyOFM+oVXwc1kMqrrKnQiMJ3lgh59LjkX4z1cDNX3MomyUMJ+I+DaWC2VdHggB74BNANSd+zkPQeNKg3o7FetlDJya1bk8ofdNBARxHFMBtMXu/ONfCT3Q2kCY9gZDRktmNRiHG/1cXhkIcN1RWrbsCkwIDAQAB",
}

Comparar IDs

Abra a página "Gerenciamento de extensões" em chrome://extensions, verifique se o modo de desenvolvedor está ativado e faça o upload do diretório de extensão descompactado. Compare o ID da extensão na página de gerenciamento de extensões com o ID do item no Painel de controle do desenvolvedor. Eles precisam ser iguais.

O ID da correspondência da extensão

Criar um ID do cliente OAuth

Acesse o Console de APIs do Google e crie um novo projeto. Quando estiver tudo pronto, selecione Credenciais na barra lateral, clique em Criar credenciais e escolha ID do cliente do OAuth.

Criar credenciais para a extensão

Na página "Criar ID do cliente", selecione Extensão do Chrome. Preencha o nome da extensão e coloque o ID da extensão no final do URL no campo "ID do aplicativo".

Preencher as informações da extensão

Para finalizar, clique em "Criar". O console vai fornecer um ID do cliente OAuth.

Registrar o OAuth no manifesto

Inclua o campo "oauth2" no manifesto da extensão. Coloque o ID do cliente OAuth gerado em "client_id". Inclua uma string vazia em "scopes" por enquanto.

{
  "name": "OAuth Tutorial FriendBlock",
  ...
  "oauth2": {
    "client_id": "yourExtensionOAuthClientIDWillGoHere.apps.googleusercontent.com",
    "scopes":[""]
  },
  ...
}

Iniciar o primeiro fluxo do OAuth

Registre a permissão identity no manifesto.

{
  "name": "OAuth Tutorial FriendBlock",
  ...
  "permissions": [
    "identity"
  ],
  ...
}

Crie um arquivo para gerenciar o fluxo OAuth chamado oauth.js e inclua o seguinte código.

window.onload = function() {
  document.querySelector('button').addEventListener('click', function() {
    chrome.identity.getAuthToken({interactive: true}, function(token) {
      console.log(token);
    });
  });
};

Coloque uma tag de script para oauth.js no cabeçalho de index.html.

...
  <head>
    <title>FriendBlock</title>
    ...
    <script type="text/javascript" src="oauth.js"></script>
  </head>
...

Recarregue a extensão e clique no ícone do navegador para abrir index.html. Abra o console e clique no botão "FriendBlock Contacts". Um token OAuth vai aparecer no console.

Conferir o token no console

Ativar a API Google People

Volte ao console da API Google e selecione Biblioteca na barra lateral. Pesquise "Google People API", clique no resultado correto e ative.

Ativar a API People

Adicione a biblioteca de cliente da API Google People a "scopes" no manifesto da extensão.

{
  "name": "OAuth Tutorial FriendBlock",
  ...
  "oauth2": {
    "client_id": "yourExtensionOAuthClientIDWillGoHere.apps.googleusercontent.com",
    "scopes": [
      "https://www.googleapis.com/auth/contacts.readonly"
    ]
  },
  ...
}

Volte ao console da API do Google e navegue até as credenciais. Clique em "Criar credenciais" e selecione "Chave de API" no menu suspenso.

Criar credenciais da API People

Mantenha a chave de API gerada para uso posterior.

Criar a primeira solicitação de API

Agora que a extensão tem as permissões e credenciais adequadas e pode autorizar um usuário do Google, ela pode solicitar dados pela API People. Atualize o código em oauth.js para que ele fique como abaixo.

window.onload = function() {
  document.querySelector('button').addEventListener('click', function() {
    chrome.identity.getAuthToken({interactive: true}, function(token) {
      let init = {
        method: 'GET',
        async: true,
        headers: {
          Authorization: 'Bearer ' + token,
          'Content-Type': 'application/json'
        },
        'contentType': 'json'
      };
      fetch(
          'https://people.googleapis.com/v1/contactGroups/all?maxMembers=20&key=API_KEY',
          init)
          .then((response) => response.json())
          .then(function(data) {
            console.log(data)
          });
    });
  });
};

Substitua API_KEY pela chave de API gerada no console da API do Google. A extensão precisa registrar um objeto JSON que inclua uma matriz de people/account_ids no campo memberResourceNames.

Bloquear rostos

Agora que a extensão está retornando uma lista dos contatos do usuário, ela pode fazer outras solicitações para extrair os perfis e as informações desses contatos . A extensão vai usar o memberResourceNames para extrair as informações de foto dos contatos do usuário. Atualize oauth.js para incluir o código abaixo.

window.onload = function() {
  document.querySelector('button').addEventListener('click', function() {
    chrome.identity.getAuthToken({interactive: true}, function(token) {
      let init = {
        method: 'GET',
        async: true,
        headers: {
          Authorization: 'Bearer ' + token,
          'Content-Type': 'application/json'
        },
        'contentType': 'json'
      };
      fetch(
          'https://people.googleapis.com/v1/contactGroups/all?maxMembers=20&key=<API_Key_Here>',
          init)
          .then((response) => response.json())
          .then(function(data) {
            let photoDiv = document.querySelector('#friendDiv');
            let returnedContacts = data.memberResourceNames;
            for (let i = 0; i < returnedContacts.length; i++) {
              fetch(
                  'https://people.googleapis.com/v1/' + returnedContacts[i] +
                      '?personFields=photos&key=API_KEY',
                  init)
                  .then((response) => response.json())
                  .then(function(data) {
                    let profileImg = document.createElement('img');
                    profileImg.src = data.photos[0].url;
                    photoDiv.appendChild(profileImg);
                  });
            };
          });
    });
  });
};

Recarregue e volte à extensão. Clique no botão "Bloquear amigo" e pronto. Aproveite as faces dos contatos em um bloco.

Contato com rostos em um bloco