Usando OAuth 2.0 para aplicativos de servidor para servidor

O sistema Google OAuth 2.0 oferece suporte a interações de servidor para servidor, como aquelas entre um aplicativo da web e um serviço do Google. Para este cenário, você precisa de uma conta de serviço , que é uma conta que pertence ao seu aplicativo em vez de a um usuário final individual. Seu aplicativo chama APIs do Google em nome da conta de serviço, portanto, os usuários não estão diretamente envolvidos. Esse cenário às vezes é chamado de "OAuth de duas pernas" ou "2LO". (O termo relacionado "OAuth de três pernas" refere-se a cenários em que seu aplicativo chama APIs do Google em nome de usuários finais e nos quais o consentimento do usuário às vezes é necessário.)

Normalmente, um aplicativo usa uma conta de serviço quando o aplicativo usa APIs do Google para trabalhar com seus próprios dados em vez dos dados de um usuário. Por exemplo, um aplicativo que usa o Google Cloud Datastore para persistência de dados usaria uma conta de serviço para autenticar suas chamadas para a API do Google Cloud Datastore.

Os administradores de domínio do Google Workspace também podem conceder às contas de serviço autoridade em todo o domínio para acessar os dados do usuário em nome dos usuários no domínio.

Este documento descreve como um aplicativo pode concluir o fluxo de servidor para servidor OAuth 2.0 usando uma biblioteca cliente de APIs do Google (recomendado) ou HTTP.

Visão geral

Para oferecer suporte a interações de servidor para servidor, primeiro crie uma conta de serviço para seu projeto no API Console. Se você deseja acessar os dados do usuário para usuários em sua conta do Google Workspace, delegue o acesso de todo o domínio à conta de serviço.

Em seguida, seu aplicativo se prepara para fazer chamadas de API autorizadas usando as credenciais da conta de serviço para solicitar um token de acesso do servidor de autenticação OAuth 2.0.

Finalmente, seu aplicativo pode usar o token de acesso para chamar APIs do Google.

Criar uma conta de serviço

As credenciais de uma conta de serviço incluem um endereço de e-mail gerado que é exclusivo e pelo menos um par de chave pública / privada. Se a delegação em todo o domínio estiver habilitada, um ID de cliente também fará parte das credenciais da conta de serviço.

Se seu aplicativo é executado no Google App Engine, uma conta de serviço é configurada automaticamente quando você cria seu projeto.

Se seu aplicativo é executado no Google Compute Engine, uma conta de serviço também é configurada automaticamente quando você cria seu projeto, mas você deve especificar os escopos aos quais seu aplicativo precisa de acesso ao criar uma instância do Google Compute Engine. Para obter mais informações, consulte Preparando uma instância para usar contas de serviço .

Se seu aplicativo não for executado no Google App Engine ou Google Compute Engine, você deve obter essas credenciais no Google API Console. Para gerar credenciais de conta de serviço ou visualizar as credenciais públicas que você já gerou, faça o seguinte:

  1. Abra o Service accounts page .
  2. If prompted, select a project, or create a new one.
  3. Clique em Criar conta de serviço .
  4. Em Detalhes da conta de serviço , digite um nome, ID e descrição para a conta de serviço e clique em Criar .
  5. Opcional: Em Permissões da conta de serviço , selecione as funções do IAM a serem concedidas à conta de serviço e clique em Continuar .
  6. Opcional: Em Conceder acesso aos usuários a esta conta de serviço , adicione os usuários ou grupos que têm permissão para usar e gerenciar a conta de serviço.
  7. Clique em chave Criar e clique em Criar .

Seu novo par de chaves pública / privada é gerado e baixado em sua máquina; serve como a única cópia da chave privada. Você é responsável por armazená-lo com segurança. Se você perder esse par de chaves, precisará gerar um novo.

Se você precisar conceder autoridade de domínio do G Suite à conta de serviço, clique no endereço de e-mail da conta de serviço que você criou e copie o valor na caixa ID exclusivo .

Para delegar autoridade à conta de serviço, use o valor que você copiou como o ID do cliente.

Você pode retornar ao API Console a qualquer momento para ver o endereço de e-mail, impressões digitais de chave pública e outras informações, ou para gerar pares de chaves públicas / privadas adicionais. Para obter mais detalhes sobre as credenciais da conta de serviço no API Console, consulte Contas de serviço no arquivo de ajuda API Console.

Anote o endereço de e-mail da conta de serviço e armazene o arquivo de chave privada da conta de serviço em um local acessível ao seu aplicativo. Seu aplicativo precisa deles para fazer chamadas de API autorizadas.

Delegar autoridade de todo o domínio à conta de serviço

Se você tiver uma conta do Google Workspace, um administrador da organização pode autorizar um aplicativo a acessar os dados do usuário em nome dos usuários no domínio do Google Workspace. Por exemplo, um aplicativo que usa a API do Google Calendar para adicionar eventos aos calendários de todos os usuários em um domínio do Google Workspace usaria uma conta de serviço para acessar a API do Google Calendar em nome dos usuários. Autorizar uma conta de serviço para acessar dados em nome de usuários em um domínio é algumas vezes referido como "delegar autoridade em todo o domínio" a uma conta de serviço.

Para delegar autoridade de todo o domínio a uma conta de serviço, primeiro habilite a delegação de todo o domínio para uma conta de serviço existente no Service accounts page ou crie uma nova conta de serviço com a delegação de todo o domínio habilitada.

Em seguida, um superadministrador do domínio do Google Workspace deve concluir as seguintes etapas:

  1. A partir do seu domínio do Google Workspace Admin Console , vá ao menu principal > Segurança> Controles API.
  2. No painel de delegação em todo o domínio , selecione Gerenciar delegação em todo o domínio .
  3. Clique em Adicionar novo .
  4. No campo ID do cliente , insira o ID do cliente da conta de serviço. Você pode encontrar o ID do cliente da sua conta de serviço em Service accounts page.
  5. No campo Escopos OAuth (delimitados por vírgulas) , insira a lista de escopos aos quais seu aplicativo deve ter acesso. Por exemplo, se seu aplicativo precisa de acesso total de todo o domínio à API do Google Drive e à API do Google Agenda, digite: https://www.googleapis.com/auth/drive, https://www.googleapis.com/auth / calendar .
  6. Clique em Autorizar .

Seu aplicativo agora tem autoridade para fazer chamadas de API como usuários em seu domínio (para "personificar" usuários). Ao se preparar para fazer chamadas de API autorizadas, você especifica o usuário a ser personificado.

Preparando-se para fazer uma chamada de API autorizada

Java

Depois de obter o endereço de e-mail do cliente e a chave privada de API Console, use a biblioteca cliente de APIs do Google para Java para criar um objeto GoogleCredential partir das credenciais da conta de serviço e dos escopos aos quais seu aplicativo precisa de acesso. Por exemplo:

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.services.sqladmin.SQLAdminScopes;

// ...

GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"))
    .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN));

Se você estiver desenvolvendo um aplicativo no Google Cloud Platform, poderá usar as credenciais padrão do aplicativo , o que pode simplificar o processo.

Delegar autoridade em todo o domínio

Se você tiver delegado acesso de todo o domínio para a conta de serviço e que pretende representar uma conta de usuário, especifique o endereço de e-mail da conta de usuário com o createDelegated método do GoogleCredential objeto. Por exemplo:

GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"))
    .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN))
    .createDelegated("user@example.com");

Use o objeto GoogleCredential para chamar APIs do Google em seu aplicativo.

Pitão

Depois de obter o endereço de e-mail do cliente e a chave privada de API Console, use a biblioteca cliente de APIs do Google para Python para concluir as seguintes etapas:

  1. Crie um objeto Credentials partir das credenciais da conta de serviço e dos escopos aos quais seu aplicativo precisa de acesso. Por exemplo:
    from google.oauth2 import service_account
    
    SCOPES = ['https://www.googleapis.com/auth/sqlservice.admin']
    SERVICE_ACCOUNT_FILE = '/path/to/service.json'
    
    credentials = service_account.Credentials.from_service_account_file(
            SERVICE_ACCOUNT_FILE, scopes=SCOPES)

    Se você estiver desenvolvendo um aplicativo no Google Cloud Platform, poderá usar as credenciais padrão do aplicativo , o que pode simplificar o processo.

  2. Delegar autoridade em todo o domínio

    Se você delegou acesso de todo o domínio à conta de serviço e deseja representar uma conta de usuário, use o método with_subject de um objeto ServiceAccountCredentials existente. Por exemplo:

    delegated_credentials = credentials.with_subject('user@example.org')

Use o objeto Credentials para chamar APIs do Google em seu aplicativo.

HTTP / REST

Depois de obter o ID do cliente e a chave privada do API Console, seu aplicativo precisa concluir as seguintes etapas:

  1. Crie um JSON Web Token (JWT, pronunciado, "jot") que inclui um cabeçalho, um conjunto de declarações e uma assinatura.
  2. Solicite um token de acesso do servidor de autorização do Google OAuth 2.0.
  3. Manipule a resposta JSON que o servidor de autorização retorna.

As seções a seguir descrevem como concluir essas etapas.

Se a resposta incluir um token de acesso, você pode usar o token de acesso para chamar uma API do Google . (Se a resposta não incluir um token de acesso, o JWT e a solicitação de token podem não estar formados corretamente ou a conta de serviço pode não ter permissão para acessar os escopos solicitados.)

Quando o token de acesso expira , seu aplicativo gera outro JWT, o assina e solicita outro token de acesso.

Seu aplicativo de servidor usa um JWT para solicitar um token do servidor de autorização do Google e, em seguida, usa o token para chamar um endpoint da API do Google. Nenhum usuário final está envolvido.

O restante desta seção descreve os detalhes da criação de um JWT, assinatura do JWT, formação da solicitação de token de acesso e tratamento da resposta.

Criação de um JWT

Um JWT é composto de três partes: um cabeçalho, um conjunto de declarações e uma assinatura. O cabeçalho e o conjunto de declarações são objetos JSON. Esses objetos JSON são serializados em bytes UTF-8 e, em seguida, codificados usando a codificação Base64url. Essa codificação fornece resiliência contra alterações de codificação devido a operações de codificação repetidas. O cabeçalho, o conjunto de declarações e a assinatura são concatenados com um caractere ponto ( . ).

Um JWT é composto da seguinte forma:

{Base64url encoded header}.{Base64url encoded claim set}.{Base64url encoded signature}

A string de base para a assinatura é a seguinte:

{Base64url encoded header}.{Base64url encoded claim set}
Formando o cabeçalho JWT

O cabeçalho consiste em dois campos que indicam o algoritmo de assinatura e o formato da asserção. Ambos os campos são obrigatórios e cada campo possui apenas um valor. Conforme algoritmos e formatos adicionais são introduzidos, este cabeçalho será alterado de acordo.

As contas de serviço contam com o algoritmo RSA SHA-256 e o ​​formato de token JWT. Como resultado, a representação JSON do cabeçalho é a seguinte:

{"alg":"RS256","typ":"JWT"}

A representação Base64url disso é a seguinte:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9
Formando o conjunto de reivindicações JWT

O conjunto de declarações JWT contém informações sobre o JWT, incluindo as permissões solicitadas (escopos), o destino do token, o emissor, a hora em que o token foi emitido e o tempo de vida do token. A maioria dos campos é obrigatória. Como o cabeçalho JWT, o conjunto de declarações JWT é um objeto JSON e é usado no cálculo da assinatura.

Reivindicações exigidas

As declarações necessárias no conjunto de declarações JWT são mostradas abaixo. Eles podem aparecer em qualquer ordem no conjunto de reivindicações.

Nome Descrição
iss O endereço de e-mail da conta de serviço.
scope Uma lista delimitada por espaço das permissões que o aplicativo solicita.
aud Um descritor do destino pretendido da asserção. Ao fazer uma solicitação de token de acesso, esse valor é sempre https://oauth2.googleapis.com/token .
exp O tempo de expiração da asserção, especificado como segundos desde 00:00:00 UTC de 1º de janeiro de 1970. Esse valor tem no máximo 1 hora após a hora emitida.
iat A hora em que a asserção foi emitida, especificada como segundos desde 00:00:00 UTC de 1º de janeiro de 1970.

A representação JSON dos campos obrigatórios em um conjunto de declarações JWT é mostrada abaixo:

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "scope": "https://www.googleapis.com/auth/devstorage.read_only",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
Reivindicações adicionais

Em alguns casos corporativos, um aplicativo pode usar a delegação de todo o domínio para agir em nome de um determinado usuário em uma organização. A permissão para executar esse tipo de personificação deve ser concedida antes que um aplicativo possa personificar um usuário e geralmente é feito por um superadministrador. Para obter mais informações, consulte Controlar o acesso à API com delegação em todo o domínio .

Para obter um token de acesso que conceda a um aplicativo acesso delegado a um recurso, inclua o endereço de e-mail do usuário na declaração JWT definida como o valor do sub .

Nome Descrição
sub O endereço de e-mail do usuário para o qual o aplicativo está solicitando acesso delegado.

Se um aplicativo não tiver permissão para representar um usuário, a resposta a uma solicitação de token de acesso que inclui o sub será um erro .

Um exemplo de um conjunto de declarações JWT que inclui o sub é mostrado abaixo:

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "sub": "some.user@example.com",
  "scope": "https://www.googleapis.com/auth/prediction",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
Codificando o conjunto de declarações JWT

Como o cabeçalho JWT, o conjunto de declarações JWT deve ser serializado para UTF-8 e codificado em Base64url-safe. Abaixo está um exemplo de uma representação JSON de um conjunto de declarações JWT:

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "scope": "https://www.googleapis.com/auth/prediction",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
Calculando a assinatura

JSON Web Signature (JWS) é a especificação que orienta a mecânica de geração da assinatura para o JWT. A entrada para a assinatura é a matriz de bytes do seguinte conteúdo:

{Base64url encoded header}.{Base64url encoded claim set}

O algoritmo de assinatura no cabeçalho JWT deve ser usado ao calcular a assinatura. O único algoritmo de assinatura compatível com o servidor de autorização do Google OAuth 2.0 é o RSA usando o algoritmo de hash SHA-256. Isso é expresso como RS256 no campo alg no cabeçalho JWT.

Assine a representação UTF-8 da entrada usando SHA256withRSA (também conhecido como RSASSA-PKCS1-V1_5-SIGN com a função hash SHA-256) com a chave privada obtida em Google API Console. A saída será uma matriz de bytes.

A assinatura deve ser codificada em Base64url. O cabeçalho, o conjunto de declarações e a assinatura são concatenados com um caractere ponto ( . ). O resultado é o JWT. Deve ser o seguinte (quebras de linha adicionadas para maior clareza):

{Base64url encoded header}.
{Base64url encoded claim set}.
{Base64url encoded signature}

Abaixo está um exemplo de um JWT antes da codificação Base64url:

{"alg":"RS256","typ":"JWT"}.
{
"iss":"761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
"scope":"https://www.googleapis.com/auth/prediction",
"aud":"https://oauth2.googleapis.com/token",
"exp":1328554385,
"iat":1328550785
}.
[signature bytes]

Abaixo está um exemplo de um JWT que foi assinado e está pronto para transmissão:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL29hdXRoMi92NC90b2tlbiIsImV4cCI6MTMyODU1NDM4NSwiaWF0IjoxMzI4NTUwNzg1fQ.UFUt59SUM2_AW4cRU8Y0BYVQsNTo4n7AFsNrqOpYiICDu37vVt-tw38UKzjmUKtcRsLLjrR3gFW3dNDMx_pL9DVjgVHDdYirtrCekUHOYoa1CMR66nxep5q5cBQ4y4u2kIgSvChCTc9pmLLNoIem-ruCecAJYgI9Ks7pTnW1gkOKs0x3YpiLpzplVHAkkHztaXiJdtpBcY1OXyo6jTQCa3Lk2Q3va1dPkh_d--GU2M5flgd8xNBPYw4vxyt0mP59XZlHMpztZt0soSgObf7G3GXArreF_6tpbFsS3z2t5zkEiHuWJXpzcYr5zWTRPDEHsejeBSG8EgpLDce2380ROQ

Fazendo a solicitação de token de acesso

Depois de gerar o JWT assinado, um aplicativo pode usá-lo para solicitar um token de acesso. Essa solicitação de token de acesso é uma solicitação HTTPS POST e o corpo é codificado por URL. O URL é mostrado abaixo:

https://oauth2.googleapis.com/token

Os seguintes parâmetros são necessários na solicitação HTTPS POST :

Nome Descrição
grant_type Use a seguinte string, codificada em URL conforme necessário: urn:ietf:params:oauth:grant-type:jwt-bearer
assertion O JWT, incluindo assinatura.

Abaixo está um dump bruto da solicitação HTTPS POST usada em uma solicitação de token de acesso:

POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU3MzM4MSwiaWF0IjoxMzI4NTY5NzgxfQ.ixOUGehweEVX_UKXv5BbbwVEdcz6AYS-6uQV6fGorGKrHf3LIJnyREw9evE-gs2bmMaQI5_UbabvI4k-mQE4kBqtmSpTzxYBL1TCd7Kv5nTZoUC1CmwmWCFqT9RE6D7XSgPUh_jF1qskLa2w0rxMSjwruNKbysgRNctZPln7cqQ

Abaixo está a mesma solicitação, usando curl :

curl -d 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU3MzM4MSwiaWF0IjoxMzI4NTY5NzgxfQ.RZVpzWygMLuL-n3GwjW1_yhQhrqDacyvaXkuf8HcJl8EtXYjGjMaW5oiM5cgAaIorrqgYlp4DPF_GuncFqg9uDZrx7pMmCZ_yHfxhSCXru3gbXrZvAIicNQZMFxrEEn4REVuq7DjkTMyCMGCY1dpMa8aWfTQFt3Eh7smLchaZsU
' https://oauth2.googleapis.com/token

Lidando com a resposta

Se o JWT e a solicitação de token de acesso estiverem formados corretamente e a conta de serviço tiver permissão para executar a operação, a resposta JSON do servidor de autorização incluirá um token de acesso. A seguir está um exemplo de resposta:

{
  "access_token": "1/8xbJqaOZXSUZbHLl5EOtu1pxz3fmmetKx9W8CV4t79M",
  "scope": "https://www.googleapis.com/auth/prediction"
  "token_type": "Bearer",
  "expires_in": 3600
}

Os tokens de acesso podem ser reutilizados durante a janela de duração especificada pelo valor expires_in .

Chamando APIs do Google

Java

Use o objeto GoogleCredential para chamar APIs do Google, concluindo as seguintes etapas:

  1. Crie um objeto de serviço para a API que deseja chamar usando o objeto GoogleCredential . Por exemplo:
    SQLAdmin sqladmin =
        new SQLAdmin.Builder(httpTransport, JSON_FACTORY, credential).build();
  2. Faça solicitações ao serviço API usando a interface fornecida pelo objeto de serviço . Por exemplo, para listar as instâncias de bancos de dados Cloud SQL no projeto emocionante-example-123:
    SQLAdmin.Instances.List instances =
        sqladmin.instances().list("exciting-example-123").execute();

Pitão

Use o objeto Credentials autorizado para chamar APIs do Google, concluindo as seguintes etapas:

  1. Crie um objeto de serviço para a API que você deseja chamar. Você constrói um objeto de serviço chamando a função de build com o nome e a versão da API e o objeto Credentials autorizado. Por exemplo, para chamar a versão 1beta3 da API de administração do Cloud SQL:
    import googleapiclient.discovery
    
    sqladmin = googleapiclient.discovery.build('sqladmin', 'v1beta3', credentials=credentials)
  2. Faça solicitações ao serviço API usando a interface fornecida pelo objeto de serviço . Por exemplo, para listar as instâncias de bancos de dados Cloud SQL no projeto emocionante-example-123:
    response = sqladmin.instances().list(project='exciting-example-123').execute()

HTTP / REST

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 serviço ou 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

Quando os tokens de acesso expiram

Os tokens de acesso emitidos pelo servidor de autorização do Google OAuth 2.0 expiram após a duração fornecida pelo valor expires_in . Quando um token de acesso expira, o aplicativo deve gerar outro JWT, assiná-lo e solicitar outro token de acesso.

Códigos de erro JWT

campo de error campo error_description Significado Como resolver
unauthorized_client Unauthorized client or scope in request. Se você estiver tentando usar a delegação em todo o domínio, a conta de serviço não está autorizada no Admin Console do domínio do usuário.

Verifique se a conta de serviço está autorizada na página Delegação em todo o domínio do Admin Console para o usuário na sub (campo).

Embora normalmente demore alguns minutos, pode levar até 24 horas para que a autorização seja propagada para todos os usuários em sua Conta do Google.

unauthorized_client Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested. Uma conta de serviço foi autorizada usando o endereço de e-mail do cliente em vez do ID do cliente (numérico) no Admin Console. Na página de delegação em todo o domínio no Admin Console, remova o cliente e adicione-o novamente com o ID numérico.
access_denied (qualquer valor) Se você estiver usando a delegação em todo o domínio, um ou mais escopos solicitados não estão autorizados no Admin Console.

Certifique-se de que a conta de serviço está autorizada na página de delegação em todo o domínio do Admin Console para o usuário na sub (campo) e que inclui todos os escopos que você está solicitando na declaração de scope de seu JWT.

Embora normalmente demore alguns minutos, pode levar até 24 horas para que a autorização seja propagada para todos os usuários em sua Conta do Google.

invalid_grant Not a valid email. O usuário não existe. Verifique se o endereço de e-mail na sub (campo) está correto.
invalid_grant

Invalid JWT: Token must be a short-lived token (60 minutes) and in a reasonable timeframe. Check your 'iat' and 'exp' values and use a clock with skew to account for clock differences between systems.

Normalmente, isso significa que a hora do sistema local não está correta. Também pode acontecer se o valor exp for mais de 65 minutos no futuro do valor iat , ou se o valor exp for menor que o valor iat .

Certifique-se de que o relógio do sistema onde o JWT é gerado esteja correto. Se necessário, sincronize seu tempo com o Google NTP .

invalid_grant Invalid JWT Signature.

A declaração JWT é assinada com uma chave privada não associada à conta de serviço identificada pelo e-mail do cliente.

Como alternativa, a asserção JWT pode ser codificada incorretamente - deve ser codificada em Base64, sem novas linhas ou preenchimento de sinais de igual.

Decodifique o conjunto de declarações JWT e verifique se a chave que assinou a declaração está associada à conta de serviço.

Tente usar uma biblioteca OAuth fornecida pelo Google para garantir que o JWT seja gerado corretamente.

invalid_scope Invalid OAuth scope or ID token audience provided. Nenhum escopo foi solicitado (lista vazia de escopos) ou um dos escopos solicitados não existe (ou seja, é inválido).

Certifique-se de que a declaração de scope (campo) do JWT seja preenchida e compare os escopos que ela contém com os escopos documentados para as APIs que você deseja usar, para garantir que não haja erros ou erros de digitação.

Observe que a lista de escopos na declaração de scope precisa ser separada por espaços, não vírgulas.

disabled_client The OAuth client was disabled. A chave usada para assinar a declaração JWT está desabilitada.

Vá para Google API Console e, em IAM & Admin> Contas de serviço , ative a conta de serviço que contém o "ID da chave" usado para assinar a declaração.

Adendo: autorização de conta de serviço sem OAuth

Com algumas APIs do Google, você pode fazer chamadas de API autorizadas usando um JWT assinado diretamente como um token do portador, em vez de um token de acesso OAuth 2.0. Quando isso for possível, você pode evitar ter que fazer uma solicitação de rede ao servidor de autorização do Google antes de fazer uma chamada de API.

Se a API que você deseja chamar tem uma definição de serviço publicada no repositório GitHub de APIs do Google , você pode fazer chamadas de API autorizadas usando um JWT em vez de um token de acesso. Para fazer isso:

  1. Crie uma conta de serviço conforme descrito acima. Certifique-se de manter o arquivo JSON obtido ao criar a conta.
  2. Usando qualquer biblioteca JWT padrão, como uma encontrada em jwt.io , crie um JWT com um cabeçalho e carga útil como o exemplo a seguir:
    {
      "alg": "RS256",
      "typ": "JWT",
      "kid": "abcdef1234567890"
    }
    .
    {
      "iss": "123456-compute@developer.gserviceaccount.com",
      "sub": "123456-compute@developer.gserviceaccount.com",
      "aud": "https://firestore.googleapis.com/",
      "iat": 1511900000,
      "exp": 1511903600
    }
    • Para o campo kid no cabeçalho, especifique o ID da chave privada da sua conta de serviço. Você pode encontrar esse valor no campo private_key_id do arquivo JSON da sua conta de serviço.
    • Para os campos iss e sub , especifique o endereço de e-mail da sua conta de serviço. Você pode encontrar esse valor no campo client_email do arquivo JSON da sua conta de serviço.
    • Para o campo aud , especifique o terminal da API. Por exemplo: https:// SERVICE .googleapis.com/ .
    • Para o campo iat , especifique a hora Unix atual e, para o campo exp , especifique a hora exatamente 3600 segundos depois, quando o JWT irá expirar.

Assine o JWT com RSA-256 usando a chave privada encontrada no arquivo JSON da sua conta de serviço.

Por exemplo:

Java

Usando google-api-java-client e java-jwt :

GoogleCredential credential =
        GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"));
PrivateKey privateKey = credential.getServiceAccountPrivateKey();
String privateKeyId = credential.getServiceAccountPrivateKeyId();

long now = System.currentTimeMillis();

try {
    Algorithm algorithm = Algorithm.RSA256(null, privateKey);
    String signedJwt = JWT.create()
        .withKeyId(privateKeyId)
        .withIssuer("123456-compute@developer.gserviceaccount.com")
        .withSubject("123456-compute@developer.gserviceaccount.com")
        .withAudience("https://firestore.googleapis.com/")
        .withIssuedAt(new Date(now))
        .withExpiresAt(new Date(now + 3600 * 1000L))
        .sign(algorithm);
} catch ...

Pitão

Usando PyJWT :

iat = time.time()
exp = iat + 3600
payload = {'iss': '123456-compute@developer.gserviceaccount.com',
           'sub': '123456-compute@developer.gserviceaccount.com',
           'aud': 'https://firestore.googleapis.com/',
           'iat': iat,
           'exp': exp}
additional_headers = {'kid': PRIVATE_KEY_ID_FROM_JSON}
signed_jwt = jwt.encode(payload, PRIVATE_KEY_FROM_JSON, headers=additional_headers,
                       algorithm='RS256')
  1. Chame a API, usando o JWT assinado como o token do portador:
    GET /v1/projects/abc/databases/123/indexes HTTP/1.1
    Authorization: Bearer SIGNED_JWT
    Host: firestore.googleapis.com