OAuth 2.0 para aplicativos Web do lado do cliente

Este documento explica como implementar a autorização OAuth 2.0 para acessar as APIs do Google 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 o 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 exigido pelo aplicativo. Você pode abrir o URL na janela atual do navegador ou em um pop-up. O usuário pode se autenticar no Google e conceder as permissões solicitadas. 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

Habilite APIs para seu projeto

Qualquer aplicativo que chame as APIs do Google precisa ativar 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 encontrá-la ou clique em Visualizar tudo na família de produtos à qual ela pertence.
  4. Selecione a API que deseja habilitar e clique no botão Habilitar .
  5. If prompted, enable billing.
  6. If prompted, read and accept the API's Terms of Service.

Criar credenciais de autorização

Qualquer aplicativo que use OAuth 2.0 para acessar as APIs do Google deve ter credenciais de autorização que identifiquem o aplicativo para o servidor OAuth 2.0 do Google. As etapas a seguir explicam como criar credenciais para seu projeto. Seus aplicativos podem usar as credenciais para acessar as APIs que você habilitou para esse 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 origens JavaScript autorizadas . As origens identificam os domínios dos quais seu aplicativo pode enviar solicitações ao servidor OAuth 2.0. Essas origens devem seguir as 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 em que permitem 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 obter o consentimento do usuário.

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

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

Como obter 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 exija autorização do usuário.

Etapa 1: configurar o objeto cliente

Se você estiver usando a biblioteca cliente de APIs do Google para JavaScript para lidar com o fluxo OAuth 2.0, sua primeira etapa é configurar os objetos gapi.auth2 e gapi.client . 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 que seu aplicativo está solicitando permissão para acessar. Esses valores informam a tela de consentimento que o Google exibe ao 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 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 faz chamadas de API autorizadas posteriormente.

O trecho de código abaixo é um trecho do exemplo completo mostrado posteriormente neste documento. Esse 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 no API Console. Observe que o clientId é obrigatório se seu aplicativo fizer solicitações de API autorizadas. Os aplicativos que fazem apenas solicitações não autorizadas podem especificar apenas 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 de descoberta de API que seu aplicativo usa. Um documento Discovery 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 da versão 3 da API do Google Drive.

Após a conclusão da chamada gapi.client.init , 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 entrada do usuário é alterado. (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);
  });
}

Pontos de extremidade OAuth 2.0

Se você estiver acessando diretamente os endpoints do OAuth 2.0, poderá prosseguir 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. Seu papel como ouvinte também foi definido no trecho 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. Esse valor pode ser definido quando o aplicativo é carregado e atualizado se o usuário entrar ou sair do aplicativo.

      Nesse snippet, a função sendAuthorizedApiRequest verifica o valor da variável para determinar se o aplicativo deve tentar uma solicitação de API que exija 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 entrar. Depois que o usuário entra, a função updateSignInStatus chama sendAuthorizedApiRequest , passando a mesma solicitação que foi tentada antes do início do fluxo de autorização.

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;
  }
}

Pontos de extremidade OAuth 2.0

Gere um URL para solicitar acesso do endpoint OAuth 2.0 do Google em https://accounts.google.com/o/oauth2/v2/auth . Esse endpoint é acessível por HTTPS; conexões HTTP simples são recusadas.

O servidor de autorização do Google é compatível com os seguintes parâmetros de string de consulta para aplicativos de servidor da web:

Parâmetros
client_id Requerido

O ID do cliente para seu aplicativo. Você pode encontrar esse valor no API ConsoleCredentials page.

redirect_uri Requerido

Determina para onde o servidor de API redireciona o usuário depois que o usuário 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 ConsoleCredentials pagedo seu cliente. Se esse 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 a barra final (' / ') devem corresponder.

response_type Requerido

Os aplicativos JavaScript precisam definir o valor do parâmetro como token . Esse valor instrui o Google Authorization Server 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 Requerido

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 ao usuário.

Os escopos permitem que seu aplicativo solicite acesso apenas aos recursos de que precisa, ao mesmo tempo em que permitem que os usuários controlem a quantidade de acesso que concedem ao seu aplicativo. Assim, há uma relação inversa entre o número de escopos solicitados e a probabilidade de obter o 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 cadeia 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árias finalidades, como direcionar o usuário para o recurso correto em seu aplicativo, enviar nonces e mitigar a falsificação de solicitação entre sites. Como seu redirect_uri pode ser adivinhado, usar 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 adicionalmente que a solicitação e a resposta tenham origem no mesmo navegador, fornecendo proteção contra ataques como cross-site solicitar 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 anteriormente o acesso ao aplicativo. Consulte a seção de autorização incremental para obter exemplos.

login_hint Opcional

Se seu aplicativo souber qual usuário está tentando autenticar, ele poderá usar esse 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 de login múltiplo 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 de prompts delimitada por espaço e sensível a maiúsculas e minúsculas para apresentar ao usuário. Se você não especificar esse parâmetro, o usuário será avisado 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 Solicitar o consentimento do usuário.
select_account Peça ao usuário para selecionar uma conta.

Exemplo 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 a URL de solicitação, redirecione o usuário para ela.

Código de amostra JavaScript

O snippet de JavaScript a seguir mostra como iniciar o fluxo de autorização em JavaScript sem usar a biblioteca de cliente de APIs do Google para JavaScript. Como esse endpoint OAuth 2.0 não oferece suporte ao compartilhamento de recursos de origem cruzada (CORS), o snippet cria um formulário que abre a solicitação para esse endpoint.

/*
 * 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 o consentimento do usuário

Nesta etapa, o usuário decide se concede ao seu aplicativo o acesso solicitado. Nesta fase, o Google exibe uma janela de consentimento que mostra o nome do seu aplicativo e os serviços de API do Google aos quais está solicitando permissão para acessar 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 pelo 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 a seguir.

Erros

As solicitações para o endpoint de autorização OAuth 2.0 do Google podem exibir mensagens de erro voltadas para o usuário em vez dos fluxos esperados de autenticação e autorização. Os códigos de erro comuns e as resoluçõ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 internos e de terceiros 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 confidenciais e restritos até que o acesso seja concedido explicitamente 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 do Android podem encontrar essa mensagem de erro ao abrir solicitações de autorização emandroid.webkit.WebView . Os desenvolvedores devem usar bibliotecas do Android, como o Google Sign-In para Android ou o 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 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 de links de aplicativos Android ou o aplicativo de navegador padrão. A biblioteca de guias personalizadas do Android 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 noWKWebView . Os desenvolvedores devem usar bibliotecas do iOS, como o Login do Google para iOS ou o 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 manipulador de links padrão do sistema operacional, que inclui os manipuladores de links universais ou o aplicativo de navegador padrão. A bibliotecaSFSafariViewController também é uma opção com suporte.

org_internal

O ID do cliente OAuth na solicitação faz parte de um projeto que limita o acesso a 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 originou 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 JavaScript autorizadas no Google API ConsoleCredentials page.

redirect_uri_mismatch

O redirect_uri passado 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 no Google API Console Credentials page.

O esquema, domínio e/ou porta do JavaScript que originou 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 JavaScript autorizadas no 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 entrada do usuário atual, essa função será chamada quando o usuário conceder o acesso solicitado ao aplicativo.

Pontos de extremidade OAuth 2.0

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 de 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 do 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 state foi especificado na solicitação do token de acesso, seu valor também será incluído na resposta.

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

Exemplo de resposta do servidor OAuth 2.0

Você pode testar esse fluxo clicando no seguinte exemplo de URL, 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

Após concluir o fluxo do OAuth 2.0, você será redirecionado para http://localhost/oauth2callback . Essa URL gerará um erro 404 NOT FOUND , a menos que sua máquina local forneça 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 obtiver um token de acesso, você poderá 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 Drive.

// 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);
});

Pontos de extremidade OAuth 2.0

Depois que seu aplicativo obtiver um token de acesso, você poderá usar o token para fazer chamadas para uma API do Google em nome de uma determinada conta de usuário se os escopos de acesso exigidos pela API tiverem sido concedidos. 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 do cabeçalho HTTP de Authorization . Quando possível, o cabeçalho HTTP é preferível, porque as strings 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 as 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 de 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 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

Código de amostra JavaScript

O snippet de código abaixo demonstra como usar CORS (Cross-origin resource sharing) 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 CORS na documentação dessa biblioteca provavelmente o ajudará a entender melhor essas solicitações.

Neste snippet 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

Demonstração de código de amostra

Esta seção contém uma demonstração funcional 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 for Google API Docs . Da mesma forma, se você revogar o acesso e atualizar essa página, esse 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 nenhuma solicitação de API.

Código de amostra JavaScript

Conforme mostrado acima, este exemplo de código é para uma página (um aplicativo) que carrega a biblioteca de 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 entrar no aplicativo. Se o usuário não tiver autorizado o aplicativo anteriormente, o aplicativo iniciará 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, você 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 precisará conceder acesso novamente na próxima vez que usar o aplicativo. No entanto, se você revogar o acesso, precisará conceder acesso 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>

Pontos de extremidade OAuth 2.0

Este exemplo de código demonstra como concluir o fluxo do 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 verificará se a página armazenou um token de acesso à API no armazenamento local do seu navegador. Em caso afirmativo, ele executa a solicitação da API. Caso contrário, ele inicia o fluxo OAuth 2.0.

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

  1. Ele direciona o usuário para o servidor OAuth 2.0 do Google, que solicita acesso ao escopo https://www.googleapis.com/auth/drive.metadata.readonly .
  2. Após 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 solicitação da API de amostra.

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

  4. Se a solicitação for executada com sucesso, 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 esse código localmente, você precisa definir valores para as variáveis YOUR_CLIENT_ID e YOUR_REDIRECT_URI que correspondem às suas credenciais de autorização . A variável YOUR_REDIRECT_URI deve ser definida para o mesmo URL em que a página está sendo veiculada. 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. Se esse valor não corresponder a um URI autorizado, você receberá um erro redirect_uri_mismatch . Seu projeto também deve ter ativado 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 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 JavaScript devem aderir 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

As origens do JavaScript 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 localhost estão isentos desta regra.

Domínio
  • Os TLDs de host ( domínios de primeiro nível ) devem pertencer à lista pública de sufixos .
  • Os domínios de host não podem ser “googleusercontent.com” .
  • As origens do JavaScript não podem conter domínios de encurtador de URL (por exemplo, goo.gl ), a menos que o aplicativo seja o proprietário do domínio.
  • Informação de usuário

    As origens do JavaScript não podem conter o subcomponente userinfo.

    Caminho

    As origens do JavaScript não podem conter o componente de caminho.

    Inquerir

    As origens do JavaScript não podem conter o componente de consulta.

    Fragmento

    As origens do JavaScript não podem conter o componente de fragmento.

    Personagens As origens do JavaScript não podem conter determinados caracteres, incluindo:
    • Caracteres curinga ( '*' )
    • Caracteres ASCII não imprimíveis
    • Codificações de porcentagem inválidas (qualquer codificação de porcentagem que não segue 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. É considerado uma prática recomendada de experiência do usuário solicitar autorização para recursos no momento em que você precisar deles. Para ativar essa prática, o servidor de autorização do Google oferece suporte à autorização incremental. Esse recurso permite solicitar escopos conforme necessário e, caso o usuário conceda 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 mixes pode precisar de poucos recursos no momento do login, talvez nada mais do que o nome da pessoa que está fazendo login. No entanto, salvar um mix concluído exigiria acesso ao Google Drive. . A maioria das pessoas acharia natural se eles só fossem solicitados a acessar o Google Drive no momento em que o aplicativo realmente precisava.

    Nesse caso, no momento do login, o aplicativo pode solicitar o openid e os escopos do profile para realizar o login básico e, posteriormente, solicitar o escopo https://www.googleapis.com/auth/drive.file no momento do a primeira solicitação para salvar uma mixagem.

    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 inseridos 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 que as concessões tenham sido solicitadas de clientes diferentes. Por exemplo, se um usuário concedesse acesso a um escopo usando o cliente de desktop de um aplicativo e, em seguida, concedesse outro escopo ao mesmo aplicativo por meio de um cliente móvel, a autorização combinada incluiria ambos os 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 método 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});

    Pontos de extremidade OAuth 2.0

    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ê armazenou os escopos para os quais seu token de acesso é válido no armazenamento local do navegador. (The complete example code stores a list of scopes for which the access token is valid by setting the oauth2-test-params.scope property in the browser's local storage.)

    The snippet compares the scopes for which the access token is valid to the scope you want to use for a particular query. If the access token does not cover that scope, the OAuth 2.0 flow starts. Here, the oauth2SignIn function is the same as the one that was provided in step 2 (and that is provided later in the complete example ).

    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.
    }

    Revoking a token

    In some cases a user may wish to revoke access given to an application. A user can revoke access by visiting Account Settings . See the Remove site or app access section of the Third-party sites & apps with access to your account support document for more information.

    It is also possible for an application to programmatically revoke the access given to it. Programmatic revocation is important in instances where a user unsubscribes, removes an application, or the API resources required by an app have significantly changed. In other words, part of the removal process can include an API request to ensure the permissions previously granted to the application are removed.

    JS Client Library

    To programmatically revoke a token, call GoogleAuth.disconnect() :

    GoogleAuth.disconnect();

    OAuth 2.0 Endpoints

    To programmatically revoke a token, your application makes a request to https://oauth2.googleapis.com/revoke and includes the token as a parameter:

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

    The token can be an access token or a refresh token. If the token is an access token and it has a corresponding refresh token, the refresh token will also be revoked.

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