Autenticação e autorização

Esta página é destinada apenas a clientes que têm uma licença antiga do Maps APIs for Work ou do Maps API for Business. Esta página não se aplica a clientes com o novo Google Maps APIs Premium Plan, disponibilizado em janeiro de 2016.

IDs de cliente e assinaturas

Ao usar os Google Maps APIs Web Services com uma licença do Google Maps APIs for Work, é preciso usar dois parâmetros de autenticação: ID de cliente e assinatura digital exclusiva (no lugar da chave de API).

Se estiver passando dos serviços Web gratuitos da API para uma implementação do Google Maps APIs for Work, você precisará remover o parâmetro key das solicitações. Os Google Maps APIs Web Services ignorarão solicitações que contenham um ID de cliente e uma chave.

Seu ID de cliente e sua assinatura

Depois de comprar a licença do Google Maps APIs for Work, você receberá um e-mail de boas-vindas do Google que contém seu ID de cliente e sua chave criptográfica privada.

  • Seu ID de cliente é usado para acessar os recursos especiais do Google Maps APIs for Work — você deve fornecer um ID de cliente ao acessar qualquer biblioteca ou serviço da API. Todos os IDs de cliente começam com um prefixo gme-. Passe o seu ID de cliente como o valor do parâmetro client.

  • Uma assinatura digital única é gerada usando a sua chave criptográfica privada. Passe essa assinatura como o valor do parâmetro signature. Veja abaixo mais informações sobre como gerar a assinatura, na seção sobre assinaturas digitais.

Veja um exemplo da Google Maps Directions API:

    https://maps.googleapis.com/maps/api/directions/json
      ?origin=Toronto
      &destination=Montreal
      &client=gme-YOUR_CLIENT_ID
      &signature=YOUR_URL_SIGNATURE

Se você perdeu seu ID de cliente ou sua chave criptográfica privada, é possível recuperá-la acessando o Google Cloud Support Portal e clicando em Maps: Manage Client ID nos links à esquerda da tela.

Parâmetro opcional para relatórios

Além dos parâmetros de autenticação, o parâmetro a seguir é opcional para solicitações do Google Maps APIs for Work:

  • channel é usado para acrescentar mais detalhes ao relatório por meio do agrupamento de diferentes canais em separado nos seus relatórios. Consulte a seção Relatórios de canal do documento Cota e relatórios dos serviços Web do Google Maps APIs for Work.

Assinaturas digitais

As solicitações de clientes do Google Maps APIs for Work às Web Service APIs exigem uma assinatura digital, gerada por meio de uma chave criptográfica privada fornecida a você no e-mail de boas-vindas.

O processo de assinatura combina um URL e a chave usando um algoritmo criptográfico. A assinatura única gerada permite que os nossos servidores verifiquem se os sites que geram solicitações usando seu ID de cliente têm autorização para fazê-lo. A assinatura também é exclusiva por URL, garantindo que as solicitações que usam seu ID de cliente não possam ser modificadas sem exigir a geração de uma nova assinatura.

Sua chave criptográfica privada

A chave criptográfica de assinatura de URL privada será emitida com seu ID de cliente e é uma “chave secreta compartilhada” entre você e a Google. Essa chave de assinatura é somente sua e é exclusiva para o seu ID de cliente. Por isso, mantenha-a confidencial. Essa chave não deve ser passada dentro de solicitações, armazenada em sites nem postada em fórum público. Qualquer pessoa que tiver em mãos essa chave de assinatura pode fazer solicitações usando a sua identidade.

Observação: Essa chave criptográfica de assinatura privada não é igual às chaves de API emitidas pelo Google API Console.

Caso tenha perdido sua chave criptográfica privada, acesse o Google Cloud Support Portal e clique em Maps: Manage Client ID para recuperá-la.

Gerar uma assinatura digital

Tentar acessar os Google Maps APIs Web Services com uma assinatura inválida resultará em um erro HTTP 403 (acesso negado). Ao converter aplicativos para usar a assinatura de URL, não deixe de testar as assinaturas para garantir que eles iniciem uma solicitação válida. Mas antes, você deve verificar se o URL original é válido e se você gerou as assinaturas corretas.

Siga estas etapas para criar uma assinatura digital para sua solicitação:

  1. Gere o URL da solicitação sem a assinatura, sem esquecer de incluir o parâmetro client. Observe que todo caractere não padrão precisa ser codificado para URL: Por exemplo, para a Directions API, construa o URL da seguinte forma:

    https://maps.googleapis.com/maps/api/directions/json?origin=Toronto&destination=Montreal&client=clientID

    Observação: todos os serviços do Google exigem a codificação de caracteres UTF-8 (que inclui ASCII implicitamente). Se seus aplicativos operarem usando outros conjuntos de caracteres, gere os URLs usando UTF-8 e codifique-os para URL.

  2. Remova a parte do domínio da solicitação, deixando apenas o caminho e a consulta: Por exemplo, para a Directions API:

    /maps/api/directions/json?origin=Toronto&destination=Montreal&client=clientID

  3. Recupere sua chave privada, que é codificada em Base64 modificado para URLs, e assine o URL acima usando o algoritmo HMAC-SHA1. Pode ser necessário decodificar essa chave no formato binário original dela. Observe que, na maioria das bibliotecas criptográficas, a assinatura gerada estará em formato binário.

    Observação: a Base64 modificada para URLs substitui os caracteres + e / da Base64 padrão por - e _, respectivamente, para que essas assinaturas Base64 não precisem mais de codificação para URL.

  4. Codifique a assinatura binária resultante usando a Base64 modificada para URLs para convertê-la em algo que possa ser passado em um URL.

  5. Vincule essa assinatura ao URL dentro de um parâmetro signature: Por exemplo, para a Directions API:

    https://maps.googleapis.com/maps/api/directions/json?origin=Toronto&destination=Montreal&client=clientID&signature=base64signature

Para ver exemplos de formas de se implementar assinatura de URL usando código no servidor, veja Exemplo de código para assinatura de URL.

Exemplo de código para assinatura de URL

As seções a seguir mostram como implementar a assinatura de URL usando código de servidor. URLs devem ser sempre assinados no servidor para evitar a exposição da sua chave criptográfica para os usuários.

Python

O exemplo abaixo usa bibliotecas Python padrão para assinar um URL. (Faça o download do código.)

#!/usr/bin/python
# -*- coding: utf-8 -*-
""" Signs a URL using a URL signing secret """

import hashlib
import hmac
import base64
import urlparse

def sign_url(input_url=None, secret=None):
  """ Sign a request URL with a URL signing secret.

      Usage:
      from urlsigner import sign_url

      signed_url = sign_url(input_url=my_url, secret=SECRET)

      Args:
      input_url - The URL to sign
      secret    - Your URL signing secret

      Returns:
      The signed request URL
  """

  if not input_url or not secret:
    raise Exception("Both input_url and secret are required")

  url = urlparse.urlparse(input_url)

  # We only need to sign the path+query part of the string
  url_to_sign = url.path + "?" + url.query

  # Decode the private key into its binary format
  # We need to decode the URL-encoded private key
  decoded_key = base64.urlsafe_b64decode(secret)

  # Create a signature using the private key and the URL-encoded
  # string using HMAC SHA1. This signature will be binary.
  signature = hmac.new(decoded_key, url_to_sign, hashlib.sha1)

  # Encode the binary signature into base64 for use within a URL
  encoded_signature = base64.urlsafe_b64encode(signature.digest())

  original_url = url.scheme + "://" + url.netloc + url.path + "?" + url.query

  # Return signed URL
  return original_url + "&signature=" + encoded_signature

if __name__ == "__main__":
  input_url = raw_input("URL to Sign: ")
  secret = raw_input("URL signing secret: ")
  print "Signed URL: " + sign_url(input_url, secret)

Java

O exemplo abaixo usa a classe java.util.Base64 disponível desde o JDK 1.8. Versões mais antigas podem precisar usar o Apache Commons ou similar. (Faça o download do código.)

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;  // JDK 1.8 only - older versions may need to use Apache Commons or similar.
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URL;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class UrlSigner {

  // Note: Generally, you should store your private key someplace safe
  // and read them into your code

  private static String keyString = "YOUR_PRIVATE_KEY";
  
  // The URL shown in these examples is a static URL which should already
  // be URL-encoded. In practice, you will likely have code
  // which assembles your URL from user or web service input
  // and plugs those values into its parameters.
  private static String urlString = "YOUR_URL_TO_SIGN";

  // This variable stores the binary key, which is computed from the string (Base64) key
  private static byte[] key;
  
  public static void main(String[] args) throws IOException,
    InvalidKeyException, NoSuchAlgorithmException, URISyntaxException {
    
    BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
    
    String inputUrl, inputKey = null;

    // For testing purposes, allow user input for the URL.
    // If no input is entered, use the static URL defined above.    
    System.out.println("Enter the URL (must be URL-encoded) to sign: ");
    inputUrl = input.readLine();
    if (inputUrl.equals("")) {
      inputUrl = urlString;
    }
    
    // Convert the string to a URL so we can parse it
    URL url = new URL(inputUrl);
 
    // For testing purposes, allow user input for the private key.
    // If no input is entered, use the static key defined above.   
    System.out.println("Enter the Private key to sign the URL: ");
    inputKey = input.readLine();
    if (inputKey.equals("")) {
      inputKey = keyString;
    }
    
    UrlSigner signer = new UrlSigner(inputKey);
    String request = signer.signRequest(url.getPath(),url.getQuery());
    
    System.out.println("Signed URL :" + url.getProtocol() + "://" + url.getHost() + request);
  }
  
  public UrlSigner(String keyString) throws IOException {
    // Convert the key from 'web safe' base 64 to binary
    keyString = keyString.replace('-', '+');
    keyString = keyString.replace('_', '/');
    System.out.println("Key: " + keyString);
    // Base64 is JDK 1.8 only - older versions may need to use Apache Commons or similar.
    this.key = Base64.getDecoder().decode(keyString);
  }

  public String signRequest(String path, String query) throws NoSuchAlgorithmException,
    InvalidKeyException, UnsupportedEncodingException, URISyntaxException {
    
    // Retrieve the proper URL components to sign
    String resource = path + '?' + query;
    
    // Get an HMAC-SHA1 signing key from the raw key bytes
    SecretKeySpec sha1Key = new SecretKeySpec(key, "HmacSHA1");

    // Get an HMAC-SHA1 Mac instance and initialize it with the HMAC-SHA1 key
    Mac mac = Mac.getInstance("HmacSHA1");
    mac.init(sha1Key);

    // compute the binary signature for the request
    byte[] sigBytes = mac.doFinal(resource.getBytes());

    // base 64 encode the binary signature
    // Base64 is JDK 1.8 only - older versions may need to use Apache Commons or similar.
    String signature = Base64.getEncoder().encodeToString(sigBytes);
    
    // convert the signature to 'web safe' base 64
    signature = signature.replace('+', '-');
    signature = signature.replace('/', '_');
    
    return resource + "&signature=" + signature;
  }
}

C#

O exemplo abaixo usa a biblioteca System.Security.Cryptography padrão para assinar uma solicitação de URL. Observe que é preciso converter a codificação Base64 padrão para implementar uma versão compatível com URL. (Faça o download do código.)

using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;

namespace SignUrl {

  public struct GoogleSignedUrl {

    public static string Sign(string url, string keyString) {
      ASCIIEncoding encoding = new ASCIIEncoding();

      // converting key to bytes will throw an exception, need to replace '-' and '_' characters first.
      string usablePrivateKey = keyString.Replace("-", "+").Replace("_", "/");
      byte[] privateKeyBytes = Convert.FromBase64String(usablePrivateKey);

      Uri uri = new Uri(url);
      byte[] encodedPathAndQueryBytes = encoding.GetBytes(uri.LocalPath + uri.Query);

      // compute the hash
      HMACSHA1 algorithm = new HMACSHA1(privateKeyBytes);
      byte[] hash = algorithm.ComputeHash(encodedPathAndQueryBytes);

      // convert the bytes to string and make url-safe by replacing '+' and '/' characters
      string signature = Convert.ToBase64String(hash).Replace("+", "-").Replace("/", "_");
            
      // Add the signature to the existing URI.
      return uri.Scheme+"://"+uri.Host+uri.LocalPath + uri.Query +"&signature=" + signature;
    }
  }

  class Program {

    static void Main() {
    
      // Note: Generally, you should store your private key someplace safe
      // and read them into your code

      const string keyString = "YOUR_PRIVATE_KEY";
  
      // The URL shown in these examples is a static URL which should already
      // be URL-encoded. In practice, you will likely have code
      // which assembles your URL from user or web service input
      // and plugs those values into its parameters.
      const  string urlString = "YOUR_URL_TO_SIGN";
      
      string inputUrl = null;
      string inputKey = null;
    
      Console.WriteLine("Enter the URL (must be URL-encoded) to sign: ");
      inputUrl = Console.ReadLine();
      if (inputUrl.Length == 0) {
        inputUrl = urlString;
      }     
    
      Console.WriteLine("Enter the Private key to sign the URL: ");
      inputKey = Console.ReadLine();
      if (inputKey.Length == 0) {
        inputKey = keyString;
      }
      
      Console.WriteLine(GoogleSignedUrl.Sign(inputUrl,inputKey));
    }
  }
}

Para fins de teste, você pode testar o URL e a chave privada a seguir para ver se a assinatura correta é gerada. Observe que esta chave privada serve exclusivamente para testes e não será validada por nenhum serviço Google.

  • URL: https://maps.googleapis.com/maps/api/geocode/json?address=New+York&client=clientID
  • Chave privada: vNIXE0xscrmjlyV-12Nj_BvUPaw=
  • Parte do URL a assinar: /maps/api/geocode/json?address=New+York&client=clientID
  • Assinatura: chaRF2hTJKOScPr-RQCEhZbSzIE=
  • URL totalmente assinado: https://maps.googleapis.com/maps/api/geocode/json?address=New+York&client=clientID&signature=chaRF2hTJKOScPr-RQCEhZbSzIE=

Exemplos em outras linguagens

Há exemplos que tratam de outras linguagens no projeto url-signing.

Solucionar problemas de autenticação

Se sua solicitação for inválida ou fornecer uma assinatura inválida, a Web Service API retornará um erro HTTP 403 (acesso negado).

Para solucionar os problemas de URLs individuais, use o depurador de assinaturas de URL. Ele permite que você valide rapidamente o URL e a assinatura gerada por seu aplicativo.

Como alternativa, os clientes do Google Maps APIs for Work podem resolver problemas de URLs específicos acessando o Google Cloud Support Portal e selecionando Resources > Google Maps online tools > URL Signing Debugger for Web Service and Image APIs.