OAuth 2.0 para aplicativos da Web do lado do cliente

Este documento explica como implementar a autorização OAuth 2.0 para acessar APIs do Google a partir de um aplicativo da web JavaScript. OAuth 2.0 permite que os usuários compartilhem dados específicos com um aplicativo, mantendo seus nomes de usuário, senhas e outras informações privadas. Por exemplo, um aplicativo pode usar OAuth 2.0 para obter permissão dos usuários para armazenar arquivos em seus Google Drives.

Esse fluxo OAuth 2.0 é chamado de fluxo de concessão implícito . Ele é projetado para aplicativos que acessam APIs apenas enquanto o usuário está presente no aplicativo. Esses aplicativos não são capazes de armazenar informações confidenciais.

Nesse fluxo, seu aplicativo abre um URL do Google que usa parâmetros de consulta para identificar seu aplicativo e o tipo de acesso à API que o aplicativo requer. Você pode abrir o URL na janela do navegador atual ou em um pop-up. O usuário pode se autenticar no Google e conceder as permissões solicitadas. Em seguida, o Google redireciona o usuário de volta ao seu aplicativo. O redirecionamento inclui um token de acesso, que seu aplicativo verifica e usa para fazer solicitações de API.

Pré-requisitos

Ative APIs para seu projeto

Qualquer aplicativo que chama APIs do Google precisa habilitar essas APIs no API Console.

Para habilitar uma API para seu projeto:

  1. Open the API Library no Google API Console.
  2. If prompted, select a project, or create a new one.
  3. O API Library lista todas as APIs disponíveis, agrupadas por família de produtos e popularidade. Se a API que você deseja ativar não estiver visível na lista, use a pesquisa para localizá-la ou clique em Exibir tudo na família de produtos à qual pertence.
  4. Selecione a API que deseja ativar e clique no botão Ativar .
  5. If prompted, enable billing.
  6. If prompted, read and accept the API's Terms of Service.

Crie credenciais de autorização

Qualquer aplicativo que usa OAuth 2.0 para acessar APIs do Google deve ter credenciais de autorização que identificam o aplicativo para o servidor OAuth 2.0 do Google. As etapas a seguir explicam como criar credenciais para seu projeto. Seus aplicativos podem então usar as credenciais para acessar APIs que você habilitou para aquele projeto.

  1. Go to the Credentials page.
  2. Clique em Criar credenciais> ID do cliente OAuth .
  3. Selecione o tipo de aplicativo da Web .
  4. Complete a forma. Os aplicativos que usam JavaScript para fazer solicitações autorizadas da API do Google devem especificar as origens autorizadas do JavaScript . As origens identificam os domínios dos quais seu aplicativo pode enviar solicitações ao servidor OAuth 2.0. Essas origens devem aderir às regras de validação do Google .

Identificar escopos de acesso

Os escopos permitem que seu aplicativo solicite acesso apenas aos recursos de que precisa, ao mesmo tempo que permite que os usuários controlem a quantidade de acesso que concedem ao seu aplicativo. Assim, pode haver uma relação inversa entre o número de escopos solicitados e a probabilidade de obtenção do consentimento do usuário.

Antes de começar a implementar a autorização OAuth 2.0, recomendamos que você identifique os escopos que seu aplicativo precisará de permissão para acessar.

O documento Escopos de API do OAuth 2.0 contém uma lista completa de escopos que você pode usar para acessar APIs do Google.

Obtenção de tokens de acesso OAuth 2.0

As etapas a seguir mostram como seu aplicativo interage com o servidor OAuth 2.0 do Google para obter o consentimento de um usuário para realizar uma solicitação de API em nome do usuário. Seu aplicativo deve ter esse consentimento antes de executar uma solicitação de API do Google que requer autorização do usuário.

Etapa 1: configurar o objeto cliente

Se você estiver usando biblioteca cliente das APIs do Google para JavaScript para lidar com o fluxo OAuth 2.0, o primeiro passo é configurar os gapi.auth2 e gapi.client objetos. Esses objetos permitem que seu aplicativo obtenha autorização do usuário e faça solicitações de API autorizadas.

O objeto cliente identifica os escopos para os quais seu aplicativo está solicitando permissão de acesso. Esses valores informam a tela de consentimento que o Google exibe para o usuário.

Biblioteca cliente JS

A biblioteca cliente JavaScript simplifica vários aspectos do processo de autorização:

  1. Ele cria o URL de redirecionamento para o servidor de autorização do Google e fornece um método para direcionar o usuário para esse URL.
  2. Ele lida com o redirecionamento desse servidor de volta para o seu aplicativo.
  3. Ele valida o token de acesso retornado pelo servidor de autorização.
  4. Ele armazena o token de acesso que o servidor de autorização envia para seu aplicativo e o recupera quando seu aplicativo subsequentemente faz chamadas de API autorizadas.

O trecho de código abaixo é um trecho do exemplo completo mostrado posteriormente neste documento. Este código inicializa o objeto gapi.client , que seu aplicativo usaria posteriormente para fazer chamadas de API. Quando esse objeto é criado, o objeto gapi.auth2 , que seu aplicativo usa para verificar e monitorar o status de autorização do usuário, também é inicializado.

A chamada para gapi.client.init especifica os seguintes campos:

  • Os valores apiKey e clientId especificam as credenciais de autorização do seu aplicativo. Conforme discutido na seção de criação de credenciais de autorização , esses valores podem ser obtidos em API Console. Observe que o clientId é necessário se seu aplicativo faz solicitações de API autorizadas. Os aplicativos que fazem apenas solicitações não autorizadas podem apenas especificar uma chave de API.
  • O campo de scope especifica uma lista delimitada por espaço de escopos de acesso que correspondem aos recursos que seu aplicativo pode acessar em nome do usuário. Esses valores informam a tela de consentimento que o Google exibe ao usuário.

    Recomendamos que seu aplicativo solicite acesso aos escopos de autorização no contexto sempre que possível. Ao solicitar acesso aos dados do usuário no contexto, por meio de autorização incremental , você ajuda os usuários a entender mais facilmente por que seu aplicativo precisa do acesso que está solicitando.

  • O campo discoveryDocs identifica uma lista de documentos API Discovery que seu aplicativo usa. Um documento de descoberta descreve a superfície de uma API, incluindo seus esquemas de recursos, e a biblioteca cliente JavaScript usa essas informações para gerar métodos que os aplicativos podem usar. Neste exemplo, o código recupera o documento de descoberta para a versão 3 da API do Google Drive.

Depois que a chamada gapi.client.init concluída, o código define a variável GoogleAuth para identificar o objeto Google Auth. Por fim, o código define um ouvinte que chama uma função quando o status de login do usuário muda. (Essa função não está definida no snippet.)

var GoogleAuth; // Google Auth object.
function initClient() {
  gapi.client.init({
      'apiKey': 'YOUR_API_KEY',
      'clientId': 'YOUR_CLIENT_ID',
      'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
      'discoveryDocs': ['https://www.googleapis.com/discovery/v1/apis/drive/v3/rest']
  }).then(function () {
      GoogleAuth = gapi.auth2.getAuthInstance();

      // Listen for sign-in state changes.
      GoogleAuth.isSignedIn.listen(updateSigninStatus);
  });
}

OAuth 2.0 Endpoints

Se você estiver acessando diretamente os pontos de extremidade OAuth 2.0, prossiga para a próxima etapa.

Etapa 2: Redirecionar para o servidor OAuth 2.0 do Google

Para solicitar permissão para acessar os dados de um usuário, redirecione o usuário para o servidor OAuth 2.0 do Google.

Biblioteca cliente JS

Chame o método GoogleAuth.signIn() para direcionar o usuário ao servidor de autorização do Google.

GoogleAuth.signIn();

Na prática, seu aplicativo pode definir um valor booleano para determinar se deve chamar o método signIn() antes de tentar fazer uma chamada de API.

O snippet de código abaixo demonstra como você iniciaria o fluxo de autorização do usuário. Observe os seguintes pontos sobre o snippet:

  • O objeto GoogleAuth referenciado no código é o mesmo que a variável global definida no snippet de código na etapa 1 .

  • A função updateSigninStatus é um ouvinte que escuta as alterações no status de autorização do usuário. Sua função como ouvinte também foi definida no snippet de código na etapa 1:
    GoogleAuth.isSignedIn.listen(updateSigninStatus);
  • O snippet define duas variáveis ​​globais adicionais:

    • isAuthorized é uma variável booleana que indica se o usuário já está conectado. Este valor pode ser definido quando o aplicativo é carregado e atualizado se o usuário entrar ou sair do aplicativo.

      Neste snippet, a função sendAuthorizedApiRequest verifica o valor da variável para determinar se o aplicativo deve tentar uma solicitação de API que requeira autorização ou solicitar que o usuário autorize o aplicativo.

    • currentApiRequest é um objeto que armazena detalhes sobre a última solicitação de API que o usuário tentou. O valor do objeto é definido quando o aplicativo chama a função sendAuthorizedApiRequest .

      Se o usuário autorizou o aplicativo, a solicitação é executada imediatamente. Caso contrário, a função redireciona o usuário para login. Depois do usuário se, a updateSignInStatus função chama sendAuthorizedApiRequest , passando o mesmo pedido que foi tentada antes do fluxo de autorização começou.

var isAuthorized;
var currentApiRequest;

/**
 * Store the request details. Then check to determine whether the user
 * has authorized the application.
 *   - If the user has granted access, make the API request.
 *   - If the user has not granted access, initiate the sign-in flow.
 */
function sendAuthorizedApiRequest(requestDetails) {
  currentApiRequest = requestDetails;
  if (isAuthorized) {
    // Make API request
    // gapi.client.request(requestDetails)

    // Reset currentApiRequest variable.
    currentApiRequest = {};
  } else {
    GoogleAuth.signIn();
  }
}

/**
 * Listener called when user completes auth flow. If the currentApiRequest
 * variable is set, then the user was prompted to authorize the application
 * before the request executed. In that case, proceed with that API request.
 */
function updateSigninStatus(isSignedIn) {
  if (isSignedIn) {
    isAuthorized = true;
    if (currentApiRequest) {
      sendAuthorizedApiRequest(currentApiRequest);
    }
  } else {
    isAuthorized = false;
  }
}

OAuth 2.0 Endpoints

Gere um URL para solicitar acesso do ponto de extremidade OAuth 2.0 do Google em https://accounts.google.com/o/oauth2/v2/auth . Este ponto de extremidade pode ser acessado por HTTPS; conexões HTTP simples são recusadas.

O servidor de autorização do Google oferece suporte aos seguintes parâmetros de string de consulta para aplicativos de servidor da web:

Parâmetros
client_id Obrigatório

O ID do cliente para seu aplicativo. Você pode encontrar esse valor em API Console Credentials page.

redirect_uri Obrigatório

Determina para onde o servidor API redireciona o usuário depois que ele conclui o fluxo de autorização. O valor deve corresponder exatamente a um dos URIs de redirecionamento autorizados para o cliente OAuth 2.0, que você configurou no API Console Credentials page do seu cliente. Se este valor não corresponder a um URI de redirecionamento autorizado para o client_id fornecido, você receberá um erro redirect_uri_mismatch .

Observe que o esquema http ou https , maiúsculas e minúsculas e barra final (' / ') devem corresponder.

response_type Obrigatório

Os aplicativos JavaScript precisam definir o valor do parâmetro como token . Este valor instrui o servidor de autorização do Google a retornar o token de acesso como um par name=value no identificador de fragmento do URI ( # ) para o qual o usuário é redirecionado após concluir o processo de autorização.

scope Obrigatório

Uma lista de escopos delimitada por espaço que identifica os recursos que seu aplicativo pode acessar em nome do usuário. Esses valores informam a tela de consentimento que o Google exibe para o usuário.

Os escopos permitem que seu aplicativo solicite acesso apenas aos recursos de que precisa, ao mesmo tempo que permite que os usuários controlem a quantidade de acesso que concedem ao seu aplicativo. Assim, existe uma relação inversa entre o número de escopos solicitados e a probabilidade de obtenção do consentimento do usuário.

Recomendamos que seu aplicativo solicite acesso aos escopos de autorização no contexto sempre que possível. Ao solicitar acesso aos dados do usuário no contexto, por meio de autorização incremental , você ajuda os usuários a entender mais facilmente por que seu aplicativo precisa do acesso que está solicitando.

state Recomendado

Especifica qualquer valor de string que seu aplicativo usa para manter o estado entre sua solicitação de autorização e a resposta do servidor de autorização. O servidor retorna o valor exato que você envia como um par name=value no identificador de fragmento de URL ( # ) do redirect_uri depois que o usuário consente ou nega a solicitação de acesso do seu aplicativo.

Você pode usar esse parâmetro para vários fins, como direcionar o usuário ao recurso correto em seu aplicativo, enviar nonces e atenuar a falsificação de solicitação entre sites. Como seu redirect_uri pode ser adivinhado, o uso de um valor de state pode aumentar sua garantia de que uma conexão de entrada é o resultado de uma solicitação de autenticação. Se você gerar uma string aleatória ou codificar o hash de um cookie ou outro valor que capture o estado do cliente, poderá validar a resposta para garantir que a solicitação e a resposta tenham origem no mesmo navegador, fornecendo proteção contra ataques como entre sites pedido de falsificação. Consulte a documentação do OpenID Connect para obter um exemplo de como criar e confirmar um token de state .

include_granted_scopes Opcional

Permite que os aplicativos usem autorização incremental para solicitar acesso a escopos adicionais no contexto. Se você definir o valor desse parâmetro como true e a solicitação de autorização for concedida, o novo token de acesso também cobrirá todos os escopos aos quais o usuário concedeu acesso ao aplicativo anteriormente. Consulte a seção de autorização incremental para exemplos.

login_hint Opcional

Se seu aplicativo souber qual usuário está tentando autenticar, ele pode usar este parâmetro para fornecer uma dica ao servidor de autenticação do Google. O servidor usa a dica para simplificar o fluxo de login, preenchendo previamente o campo de e-mail no formulário de login ou selecionando a sessão multi-login apropriada.

Defina o valor do parâmetro como um endereço de e-mail ou sub , que é equivalente ao ID do Google do usuário.

prompt Opcional

Uma lista delimitada por espaço e com distinção entre maiúsculas e minúsculas de prompts para apresentar ao usuário. Se você não especificar este parâmetro, o usuário será solicitado apenas na primeira vez que seu projeto solicitar acesso. Consulte Solicitando novo consentimento para obter mais informações.

Os valores possíveis são:

none Não exiba nenhuma tela de autenticação ou consentimento. Não deve ser especificado com outros valores.
consent Solicite consentimento do usuário.
select_account Peça ao usuário para selecionar uma conta.

Amostra de redirecionamento para o servidor de autorização do Google

Um exemplo de URL é mostrado abaixo, com quebras de linha e espaços para facilitar a leitura.

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly&
 include_granted_scopes=true&
 response_type=token&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

Depois de criar o URL de solicitação, redirecione o usuário para ele.

Amostra de código JavaScript

O seguinte snippet de JavaScript mostra como iniciar o fluxo de autorização em JavaScript sem usar a biblioteca cliente de APIs do Google para JavaScript. Como este ponto de extremidade OAuth 2.0 não suporta Compartilhamento de Recursos de Origem Cruzada (CORS), o snippet cria um formulário que abre a solicitação para esse ponto de extremidade.

/*
 * Create form to request access token from Google's OAuth 2.0 server.
 */
function oauthSignIn() {
  // Google's OAuth 2.0 endpoint for requesting an access token
  var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';

  // Create <form> element to submit parameters to OAuth 2.0 endpoint.
  var form = document.createElement('form');
  form.setAttribute('method', 'GET'); // Send as a GET request.
  form.setAttribute('action', oauth2Endpoint);

  // Parameters to pass to OAuth 2.0 endpoint.
  var params = {'client_id': 'YOUR_CLIENT_ID',
                'redirect_uri': 'YOUR_REDIRECT_URI',
                'response_type': 'token',
                'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
                'include_granted_scopes': 'true',
                'state': 'pass-through value'};

  // Add form parameters as hidden input values.
  for (var p in params) {
    var input = document.createElement('input');
    input.setAttribute('type', 'hidden');
    input.setAttribute('name', p);
    input.setAttribute('value', params[p]);
    form.appendChild(input);
  }

  // Add form to page and submit it to open the OAuth 2.0 endpoint.
  document.body.appendChild(form);
  form.submit();
}

Etapa 3: o Google solicita consentimento do usuário

Nesta etapa, o usuário decide se concederá ao aplicativo o acesso solicitado. Nesse estágio, o Google exibe uma janela de consentimento que mostra o nome de seu aplicativo e os serviços de API do Google aos quais está solicitando permissão de acesso com as credenciais de autorização do usuário e um resumo dos escopos de acesso a serem concedidos. O usuário pode, então, consentir em conceder acesso a um ou mais escopos solicitados por seu aplicativo ou recusar a solicitação.

Seu aplicativo não precisa fazer nada neste estágio, pois aguarda a resposta do servidor OAuth 2.0 do Google indicando se algum acesso foi concedido. Essa resposta é explicada na etapa seguinte.

Erros

As solicitações para o ponto de extremidade de autorização OAuth 2.0 do Google podem exibir mensagens de erro direcionadas ao usuário em vez dos fluxos de autenticação e autorização esperados. Códigos de erro comuns e soluções sugeridas estão listados abaixo.

admin_policy_enforced

A Conta do Google não pode autorizar um ou mais escopos solicitados devido às políticas do administrador do Google Workspace. Consulte o artigo de ajuda do administrador do Google Workspace Controlar quais aplicativos de terceiros e internos acessam os dados do Google Workspace para obter mais informações sobre como um administrador pode restringir o acesso a todos os escopos ou escopos sensíveis e restritos até que o acesso seja explicitamente concedido ao seu ID de cliente OAuth.

disallowed_useragent

O endpoint de autorização é exibido dentro de um user-agent incorporado não permitido pelas políticas OAuth 2.0 do Google.

Android

Os desenvolvedores Android podem encontrar essa mensagem de erro ao abrir solicitações de autorização em android.webkit.WebView . Em vez disso, os desenvolvedores devem usar bibliotecas Android, como o Google Sign-In para Android ou AppAuth da OpenID Foundation para Android .

Os desenvolvedores da web podem encontrar esse erro quando um aplicativo Android abre um link geral da web em um agente de usuário incorporado e um usuário navega para o endpoint de autorização OAuth 2.0 do Google a partir do seu site. Os desenvolvedores devem permitir que links gerais sejam abertos no gerenciador de links padrão do sistema operacional, que inclui os gerenciadores delinks de aplicativos Android ou o aplicativo de navegador padrão. A biblioteca Android Custom Tabs também é uma opção compatível.

iOS

Os desenvolvedores de iOS e macOS podem encontrar esse erro ao abrir solicitações de autorização no WKWebView . Em vez disso, os desenvolvedores devem usar bibliotecas iOS, como o Google Sign-In para iOS ou AppAuth da OpenID Foundation para iOS .

Os desenvolvedores da web podem encontrar esse erro quando um aplicativo iOS ou macOS abre um link geral da web em um user-agent incorporado e um usuário navega para o endpoint de autorização OAuth 2.0 do Google a partir do seu site. Os desenvolvedores devem permitir que links gerais sejam abertos no gerenciador de links padrão do sistema operacional, que inclui os gerenciadores delinks universais ou o aplicativo de navegador padrão. A biblioteca SFSafariViewController também é uma opção com suporte.

org_internal

O ID do cliente OAuth na solicitação é parte de um projeto que limita o acesso às contas do Google em uma organização específica do Google Cloud . Para obter mais informações sobre essa opção de configuração, consulte a seção Tipo de usuário no artigo de ajuda Configurando sua tela de consentimento OAuth.

origin_mismatch

O esquema, domínio e / ou porta do JavaScript que origina a solicitação de autorização pode não corresponder a um URI de origem JavaScript autorizado registrado para o ID do cliente OAuth. Revise as origens de JavaScript autorizadas em Google API Console Credentials page.

redirect_uri_mismatch

O redirect_uri transmitido na solicitação de autorização não corresponde a um URI de redirecionamento autorizado para o ID do cliente OAuth. Revise os URIs de redirecionamento autorizados em Google API Console Credentials page.

O esquema, domínio e / ou porta do JavaScript que origina a solicitação de autorização pode não corresponder a um URI de origem JavaScript autorizado registrado para o ID do cliente OAuth. Revise as origens de JavaScript autorizadas em Google API Console Credentials page.

Etapa 4: lidar com a resposta do servidor OAuth 2.0

Biblioteca cliente JS

A biblioteca cliente JavaScript lida com a resposta do servidor de autorização do Google. Se você definir um ouvinte para monitorar as alterações no estado de login do usuário atual, essa função será chamada quando o usuário conceder o acesso solicitado ao aplicativo.

OAuth 2.0 Endpoints

O servidor OAuth 2.0 envia uma resposta ao redirect_uri especificado em sua solicitação de token de acesso.

Se o usuário aprovar a solicitação, a resposta conterá um token de acesso. Se o usuário não aprovar a solicitação, a resposta conterá uma mensagem de erro. O token de acesso ou mensagem de erro é retornado no fragmento hash do URI de redirecionamento, conforme mostrado abaixo:

  • Uma resposta de token de acesso:

    https://oauth2.example.com/callback#access_token=4/P7q7W91&token_type=Bearer&expires_in=3600

    Além do parâmetro access_token , a string de fragmento também contém o parâmetro token_type , que é sempre definido como Bearer , e o parâmetro expires_in , que especifica o tempo de vida do token, em segundos. Se o parâmetro de state foi especificado na solicitação de token de acesso, seu valor também será incluído na resposta.

  • Uma resposta de erro:
    https://oauth2.example.com/callback#error=access_denied

Amostra de resposta do servidor OAuth 2.0

Você pode testar esse fluxo clicando no seguinte URL de amostra, que solicita acesso somente leitura para visualizar metadados de arquivos em seu Google Drive:

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly&
 include_granted_scopes=true&
 response_type=token&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

Depois de concluir o fluxo do OAuth 2.0, você será redirecionado para http://localhost/oauth2callback . Essa URL produzirá um erro 404 NOT FOUND a menos que sua máquina local veicule um arquivo nesse endereço. A próxima etapa fornece mais detalhes sobre as informações retornadas no URI quando o usuário é redirecionado de volta ao seu aplicativo.

Chamando APIs do Google

Biblioteca cliente JS

Depois que seu aplicativo obtém um token de acesso, você pode usar a biblioteca cliente JavaScript para fazer solicitações de API em nome do usuário. A biblioteca cliente gerencia o token de acesso para você, e você não precisa fazer nada especial para enviá-lo na solicitação.

A biblioteca cliente oferece suporte a duas maneiras de chamar métodos de API. Se você carregou um documento de descoberta, a API definirá funções específicas do método para você. Você também pode usar a função gapi.client.request para chamar um método de API. Os dois snippets a seguir demonstram essas opções para o método about.get da API do about.get .

// Example 1: Use method-specific function
var request = gapi.client.drive.about.get({'fields': 'user'});

// Execute the API request.
request.execute(function(response) {
  console.log(response);
});


// Example 2: Use gapi.client.request(args) function
var request = gapi.client.request({
  'method': 'GET',
  'path': '/drive/v3/about',
  'params': {'fields': 'user'}
});
// Execute the API request.
request.execute(function(response) {
  console.log(response);
});

OAuth 2.0 Endpoints

Depois que seu aplicativo obtém um token de acesso, você pode usar o token para fazer chamadas para uma API do Google em nome de uma determinada conta de usuário se o (s) escopo (s) de acesso exigido pela API tiver sido concedido. Para fazer isso, inclua o token de acesso em uma solicitação à API, incluindo um parâmetro de consulta access_token ou um valor de Bearer cabeçalho HTTP de Authorization . Quando possível, o cabeçalho HTTP é preferível, porque as sequências de consulta tendem a ser visíveis nos logs do servidor. Na maioria dos casos, você pode usar uma biblioteca cliente para configurar suas chamadas para APIs do Google (por exemplo, ao chamar a API Drive Files ).

Você pode experimentar todas as APIs do Google e visualizar seus escopos no OAuth 2.0 Playground .

Exemplos HTTP GET

Uma chamada para o endpoint drive.files (a API Drive Files) usando o cabeçalho HTTP Authorization: Bearer pode ter a seguinte aparência. Observe que você precisa especificar seu próprio token de acesso:

GET /drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token

Aqui está uma chamada para a mesma API para o usuário autenticado usando o parâmetro de string de consulta access_token :

GET https://www.googleapis.com/drive/v2/files?access_token=access_token

exemplos de curl

Você pode testar esses comandos com o aplicativo de linha de comando curl . Aqui está um exemplo que usa a opção de cabeçalho HTTP (preferencial):

curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files

Ou, alternativamente, a opção de parâmetro de string de consulta:

curl https://www.googleapis.com/drive/v2/files?access_token=access_token

Amostra de código JavaScript

O trecho de código abaixo demonstra como usar CORS (Compartilhamento de recursos de origem cruzada) para enviar uma solicitação a uma API do Google. Este exemplo não usa a biblioteca cliente de APIs do Google para JavaScript. No entanto, mesmo se você não estiver usando a biblioteca cliente, o guia de suporte do CORS na documentação dessa biblioteca provavelmente o ajudará a entender melhor essas solicitações.

Neste trecho de código, a variável access_token representa o token que você obteve para fazer solicitações de API em nome do usuário autorizado. O exemplo completo demonstra como armazenar esse token no armazenamento local do navegador e recuperá-lo ao fazer uma solicitação de API.

var xhr = new XMLHttpRequest();
xhr.open('GET',
    'https://www.googleapis.com/drive/v3/about?fields=user&' +
    'access_token=' + params['access_token']);
xhr.onreadystatechange = function (e) {
  console.log(xhr.response);
};
xhr.send(null);

Exemplo completo

Biblioteca cliente JS

Amostra de demonstração de código

Esta seção contém uma demonstração de trabalho do exemplo de código a seguir para demonstrar como o código se comporta em um aplicativo real. Depois de autorizar o aplicativo, ele será listado entre os aplicativos conectados à sua Conta do Google . O aplicativo é denominado OAuth 2.0 Demo para Google API Docs . Da mesma forma, se você revogar o acesso e atualizar a página, o aplicativo não será mais listado.

Observe que este aplicativo solicita acesso ao escopo https://www.googleapis.com/auth/drive.metadata.readonly . O acesso é solicitado apenas para demonstrar como iniciar o fluxo OAuth 2.0 em um aplicativo JavaScript. Este aplicativo não faz solicitações de API.

Amostra de código JavaScript

Conforme mostrado acima, este exemplo de código é para uma página (um aplicativo) que carrega a biblioteca cliente de APIs do Google para JavaScript e inicia o fluxo OAuth 2.0. A página exibe:

  • Um botão que permite ao usuário fazer login no aplicativo. Se o usuário não autorizou anteriormente o aplicativo, o aplicativo inicia o fluxo OAuth 2.0.
  • Dois botões que permitem ao usuário sair do aplicativo ou revogar o acesso concedido anteriormente ao aplicativo. Se você sair de um aplicativo, não revogou o acesso concedido ao aplicativo. Você precisará fazer login novamente antes que o aplicativo possa fazer outras solicitações autorizadas em seu nome, mas não será necessário conceder acesso novamente na próxima vez que usar o aplicativo. No entanto, se você revogar o acesso, precisará concedê-lo novamente.

Você também pode revogar o acesso ao aplicativo por meio da página Permissões da sua Conta do Google. O aplicativo está listado como OAuth 2.0 Demo para Google API Docs .

<script>
  var GoogleAuth;
  var SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly';
  function handleClientLoad() {
    // Load the API's client and auth2 modules.
    // Call the initClient function after the modules load.
    gapi.load('client:auth2', initClient);
  }

  function initClient() {
    // In practice, your app can retrieve one or more discovery documents.
    var discoveryUrl = 'https://www.googleapis.com/discovery/v1/apis/drive/v3/rest';

    // Initialize the gapi.client object, which app uses to make API requests.
    // Get API key and client ID from API Console.
    // 'scope' field specifies space-delimited list of access scopes.
    gapi.client.init({
        'apiKey': 'YOUR_API_KEY',
        'clientId': 'YOUR_CLIENT_ID',
        'discoveryDocs': [discoveryUrl],
        'scope': SCOPE
    }).then(function () {
      GoogleAuth = gapi.auth2.getAuthInstance();

      // Listen for sign-in state changes.
      GoogleAuth.isSignedIn.listen(updateSigninStatus);

      // Handle initial sign-in state. (Determine if user is already signed in.)
      var user = GoogleAuth.currentUser.get();
      setSigninStatus();

      // Call handleAuthClick function when user clicks on
      //      "Sign In/Authorize" button.
      $('#sign-in-or-out-button').click(function() {
        handleAuthClick();
      });
      $('#revoke-access-button').click(function() {
        revokeAccess();
      });
    });
  }

  function handleAuthClick() {
    if (GoogleAuth.isSignedIn.get()) {
      // User is authorized and has clicked "Sign out" button.
      GoogleAuth.signOut();
    } else {
      // User is not signed in. Start Google auth flow.
      GoogleAuth.signIn();
    }
  }

  function revokeAccess() {
    GoogleAuth.disconnect();
  }

  function setSigninStatus() {
    var user = GoogleAuth.currentUser.get();
    var isAuthorized = user.hasGrantedScopes(SCOPE);
    if (isAuthorized) {
      $('#sign-in-or-out-button').html('Sign out');
      $('#revoke-access-button').css('display', 'inline-block');
      $('#auth-status').html('You are currently signed in and have granted ' +
          'access to this app.');
    } else {
      $('#sign-in-or-out-button').html('Sign In/Authorize');
      $('#revoke-access-button').css('display', 'none');
      $('#auth-status').html('You have not authorized this app or you are ' +
          'signed out.');
    }
  }

  function updateSigninStatus() {
    setSigninStatus();
  }
</script>

<button id="sign-in-or-out-button"
        style="margin-left: 25px">Sign In/Authorize</button>
<button id="revoke-access-button"
        style="display: none; margin-left: 25px">Revoke access</button>

<div id="auth-status" style="display: inline; padding-left: 25px"></div><hr>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script async defer src="https://apis.google.com/js/api.js"
        onload="this.onload=function(){};handleClientLoad()"
        onreadystatechange="if (this.readyState === 'complete') this.onload()">
</script>

Endpoints OAuth 2.0

Este exemplo de código demonstra como concluir o fluxo OAuth 2.0 em JavaScript sem usar a biblioteca cliente de APIs do Google para JavaScript. O código é para uma página HTML que exibe um botão para tentar uma solicitação de API. Se você clicar no botão, o código verifica se a página armazenou um token de acesso da API no armazenamento local do seu navegador. Nesse caso, ele executa a solicitação da API. Caso contrário, ele inicia o fluxo do OAuth 2.0.

Para o fluxo OAuth 2.0, a página segue estas etapas:

  1. Ele direciona o usuário ao servidor OAuth 2.0 do Google, que solicita acesso ao escopo https://www.googleapis.com/auth/drive.metadata.readonly .
  2. Depois de conceder (ou negar) acesso a um ou mais escopos solicitados, o usuário é redirecionado para a página original, que analisa o token de acesso da string identificadora do fragmento.
  3. A página usa o token de acesso para fazer a amostra de solicitação da API.

    A solicitação de API chama o método about.get da API do about.get para recuperar informações sobre a conta do Google Drive do usuário autorizado.

  4. Se a solicitação for executada com êxito, a resposta da API será registrada no console de depuração do navegador.

Você pode revogar o acesso ao aplicativo por meio da página Permissões da sua Conta do Google. O aplicativo será listado como OAuth 2.0 Demo para Google API Docs .

Para executar este código localmente, você precisa definir valores para os YOUR_CLIENT_ID e YOUR_REDIRECT_URI variáveis que correspondem à sua credenciais de autorização . A variável YOUR_REDIRECT_URI deve ser definida para o mesmo URL onde a página está sendo servida. O valor deve corresponder exatamente a um dos URIs de redirecionamento autorizados para o cliente OAuth 2.0, que você configurou em API Console Credentials page. Se este valor não corresponder a um URI autorizado, você receberá um erro redirect_uri_mismatch . Seu projeto também deve ter habilitado a API apropriada para esta solicitação.

<html><head></head><body>
<script>
  var YOUR_CLIENT_ID = 'REPLACE_THIS_VALUE';
  var YOUR_REDIRECT_URI = 'REPLACE_THIS_VALUE';
  var fragmentString = location.hash.substring(1);

  // Parse query string to see if page request is coming from OAuth 2.0 server.
  var params = {};
  var regex = /([^&=]+)=([^&]*)/g, m;
  while (m = regex.exec(fragmentString)) {
    params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
  }
  if (Object.keys(params).length > 0) {
    localStorage.setItem('oauth2-test-params', JSON.stringify(params) );
    if (params['state'] && params['state'] == 'try_sample_request') {
      trySampleRequest();
    }
  }

  // If there's an access token, try an API request.
  // Otherwise, start OAuth 2.0 flow.
  function trySampleRequest() {
    var params = JSON.parse(localStorage.getItem('oauth2-test-params'));
    if (params && params['access_token']) {
      var xhr = new XMLHttpRequest();
      xhr.open('GET',
          'https://www.googleapis.com/drive/v3/about?fields=user&' +
          'access_token=' + params['access_token']);
      xhr.onreadystatechange = function (e) {
        if (xhr.readyState === 4 && xhr.status === 200) {
          console.log(xhr.response);
        } else if (xhr.readyState === 4 && xhr.status === 401) {
          // Token invalid, so prompt for user permission.
          oauth2SignIn();
        }
      };
      xhr.send(null);
    } else {
      oauth2SignIn();
    }
  }

  /*
   * Create form to request access token from Google's OAuth 2.0 server.
   */
  function oauth2SignIn() {
    // Google's OAuth 2.0 endpoint for requesting an access token
    var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';

    // Create element to open OAuth 2.0 endpoint in new window.
    var form = document.createElement('form');
    form.setAttribute('method', 'GET'); // Send as a GET request.
    form.setAttribute('action', oauth2Endpoint);

    // Parameters to pass to OAuth 2.0 endpoint.
    var params = {'client_id': YOUR_CLIENT_ID,
                  'redirect_uri': YOUR_REDIRECT_URI,
                  'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
                  'state': 'try_sample_request',
                  'include_granted_scopes': 'true',
                  'response_type': 'token'};

    // Add form parameters as hidden input values.
    for (var p in params) {
      var input = document.createElement('input');
      input.setAttribute('type', 'hidden');
      input.setAttribute('name', p);
      input.setAttribute('value', params[p]);
      form.appendChild(input);
    }

    // Add form to page and submit it to open the OAuth 2.0 endpoint.
    document.body.appendChild(form);
    form.submit();
  }
</script>

<button onclick="trySampleRequest();">Try sample request</button>
</body></html>

Regras de validação de origem de JavaScript

O Google aplica as seguintes regras de validação às origens do JavaScript para ajudar os desenvolvedores a manter seus aplicativos seguros. Suas origens de JavaScript devem obedecer a essas regras. Consulte a seção 3 da RFC 3986 para obter a definição de domínio, host e esquema, mencionados abaixo.

Regras de validação
Esquema

URIs devem usar o esquema HTTPS, não HTTP simples. URIs de host local (incluindo URIs de endereço IP de host local) estão isentos desta regra.

Hospedeiro

Os hosts não podem ser endereços IP brutos. Os endereços IP do host local estão isentos desta regra.

Domínio
  • Os TLDs de host ( domínios de nível superior ) devem pertencer à lista pública de sufixos .
  • Domínios de host não podem ser “googleusercontent.com” .
  • URIs não podem conter domínios encurtadores de URL (por exemplo, goo.gl ), a menos que o aplicativo seja proprietário do domínio.
  • Personagens URIs não podem conter certos caracteres, incluindo:
    • Caracteres curinga ( '*' )
    • Caracteres ASCII não imprimíveis
    • Codificações de porcentagem inválidas (qualquer codificação de porcentagem que não siga a forma de codificação de URL de um sinal de porcentagem seguido por dois dígitos hexadecimais)
    • Caracteres nulos (um caractere NULL codificado, por exemplo, %00 , %C0%80 )

    Autorização incremental

    No protocolo OAuth 2.0, seu aplicativo solicita autorização para acessar recursos, que são identificados por escopos. É considerada uma prática recomendada para a experiência do usuário solicitar autorização para recursos no momento em que você precisa deles. Para habilitar essa prática, o servidor de autorização do Google oferece suporte para autorização incremental. Este recurso permite solicitar escopos conforme necessário e, se o usuário conceder permissão para o novo escopo, retorna um código de autorização que pode ser trocado por um token contendo todos os escopos que o usuário concedeu ao projeto.

    Por exemplo, um aplicativo que permite que as pessoas experimentem faixas de música e criem mixagens pode precisar de poucos recursos no momento do login, talvez nada mais do que o nome da pessoa que faz login. No entanto, salvar uma mixagem completa exigiria acesso ao Google Drive . A maioria das pessoas acharia natural se o acesso ao Google Drive fosse solicitado apenas no momento em que o aplicativo realmente precisasse.

    Nesse caso, no momento do login, o aplicativo pode solicitar os escopos openid e profile para realizar o login básico e, posteriormente, solicitar o escopo https://www.googleapis.com/auth/drive.file no momento de o primeiro pedido para salvar um mix.

    As seguintes regras se aplicam a um token de acesso obtido de uma autorização incremental:

    • O token pode ser usado para acessar recursos correspondentes a qualquer um dos escopos incluídos na nova autorização combinada.
    • Quando você usa o token de atualização para a autorização combinada para obter um token de acesso, o token de acesso representa a autorização combinada e pode ser usado para qualquer um dos valores de scope incluídos na resposta.
    • A autorização combinada inclui todos os escopos que o usuário concedeu ao projeto de API, mesmo se as concessões foram solicitadas de clientes diferentes. Por exemplo, se um usuário concedeu acesso a um escopo usando um cliente de desktop do aplicativo e, em seguida, concedeu outro escopo ao mesmo aplicativo por meio de um cliente móvel, a autorização combinada incluiria os dois escopos.
    • Se você revogar um token que representa uma autorização combinada, o acesso a todos os escopos dessa autorização em nome do usuário associado será revogado simultaneamente.

    Os exemplos de código abaixo mostram como adicionar escopos a um token de acesso existente. Essa abordagem permite que seu aplicativo evite ter que gerenciar vários tokens de acesso.

    Biblioteca cliente JS

    Para adicionar escopos a um token de acesso existente, chame o GoogleUser.grant(options) . O objeto de options identifica os escopos adicionais aos quais você deseja conceder acesso.

    // Space-separated list of additional scope(s) you are requesting access to.
    // This code adds read-only access to the user's calendars via the Calendar API.
    var NEW_SCOPES = 'https://www.googleapis.com/auth/calendar.readonly';
    
    // Retrieve the GoogleUser object for the current user.
    var GoogleUser = GoogleAuth.currentUser.get();
    GoogleUser.grant({'scope': NEW_SCOPES});

    OAuth 2.0 Endpoints

    Para adicionar escopos a um token de acesso existente, inclua o parâmetro include_granted_scopes em sua solicitação ao servidor OAuth 2.0 do Google .

    O trecho de código a seguir demonstra como fazer isso. O snippet pressupõe que você tenha armazenado os escopos para os quais seu token de acesso é válido no armazenamento local do navegador. (O código de exemplo completo armazena uma lista de escopos para os quais o token de acesso é válido, definindo a propriedade oauth2-test-params.scope no armazenamento local do navegador.)

    O snippet compara os escopos para os quais o token de acesso é válido com o escopo que você deseja usar para uma consulta específica. Se o token de acesso não cobrir esse escopo, o fluxo do OAuth 2.0 será iniciado. Aqui, a função oauth2SignIn é a mesma que foi fornecida na etapa 2 (e que é fornecida posteriormente no exemplo completo ).

    var SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly';
    var params = JSON.parse(localStorage.getItem('oauth2-test-params'));
    
    var current_scope_granted = false;
    if (params.hasOwnProperty('scope')) {
      var scopes = params['scope'].split(' ');
      for (var s = 0; s < scopes.length; s++) {
        if (SCOPE == scopes[s]) {
          current_scope_granted = true;
        }
      }
    }
    
    if (!current_scope_granted) {
      oauth2SignIn(); // This function is defined elsewhere in this document.
    } else {
      // Since you already have access, you can proceed with the API request.
    }

    Revogando um token

    Em alguns casos, um usuário pode desejar revogar o acesso concedido a um aplicativo. Um usuário pode revogar o acesso visitando as Configurações da conta . Consulte a seção Remover acesso ao site ou aplicativo de Sites e aplicativos de terceiros com acesso ao documento de suporte de sua conta para obter mais informações.

    Também é possível que um aplicativo revogue programaticamente o acesso concedido a ele. A revogação programática é importante nos casos em que um usuário cancela a assinatura, remove um aplicativo ou os recursos de API exigidos por um aplicativo mudaram significativamente. Em outras palavras, parte do processo de remoção pode incluir uma solicitação de API para garantir que as permissões concedidas anteriormente ao aplicativo sejam removidas.

    Biblioteca cliente JS

    Para revogar programaticamente um token, chame GoogleAuth.disconnect() :

    GoogleAuth.disconnect();

    Endpoints OAuth 2.0

    Para revogar programaticamente um token, seu aplicativo faz uma solicitação para https://oauth2.googleapis.com/revoke e inclui o token como um parâmetro:

    curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \
            https://oauth2.googleapis.com/revoke?token={token}

    O token pode ser um token de acesso ou um token de atualização. Se o token for um token de acesso e tiver um token de atualização correspondente, o token de atualização também será revogado.

    If the revocation is successfully processed, then the HTTP status code of the response is 200 . For error conditions, an HTTP status code 400 is returned along with an error code.

    The following JavaScript snippet shows how to revoke a token in JavaScript without using the Google APIs Client Library for JavaScript. Since the Google's OAuth 2.0 endpoint for revoking tokens does not support Cross-origin Resource Sharing (CORS), the code creates a form and submits the form to the endpoint rather than using the XMLHttpRequest() method to post the request.

    function revokeAccess(accessToken) {
      // Google's OAuth 2.0 endpoint for revoking access tokens.
      var revokeTokenEndpoint = 'https://oauth2.googleapis.com/revoke';
    
      // Create <form> element to use to POST data to the OAuth 2.0 endpoint.
      var form = document.createElement('form');
      form.setAttribute('method', 'post');
      form.setAttribute('action', revokeTokenEndpoint);
    
      // Add access token to the form so it is set as value of 'token' parameter.
      // This corresponds to the sample curl request, where the URL is:
      //      https://oauth2.googleapis.com/revoke?token={token}
      var tokenField = document.createElement('input');
      tokenField.setAttribute('type', 'hidden');
      tokenField.setAttribute('name', 'token');
      tokenField.setAttribute('value', accessToken);
      form.appendChild(tokenField);
    
      // Add form to page and submit it to actually revoke the token.
      document.body.appendChild(form);
      form.submit();
    }