API Directions: acessar uma chave de API

Observação: o plano Premium da Plataforma Google Maps não está mais disponível para a inscrição de novos clientes.

Escolher um método de autenticação

Para usar a Plataforma Google Maps, é preciso autenticar solicitações com uma chave de API ou um ID de cliente e uma assinatura digital.

O método de autenticação que você escolher é definido com base na sua licença:

  • Os clientes do plano Premium podem usar uma chave de API ou um ID do cliente e uma assinatura digital.
  • Os clientes com uma licença anterior precisam usar um ID e uma assinatura digital.

Para escolher o método de autenticação a ser usado, considere o seguinte:

  • Autenticação com uma chave de API (plano Premium)
    Ao usar uma chave de API para autenticar sua solicitação, você pode fazer o seguinte:
    • Gerenciar todas as suas APIs na página "APIs" do Console do Google Cloud
    • Acessar o uso de dados em tempo real e 30 dias do histórico de uso de dados na página "APIs" do Console do Cloud
    • Adicionar o parâmetro channel às solicitações para ver relatórios de uso mais detalhados
    • Ver relatórios de uso com mais de 30 dias de dados no Console do Google Cloud
  • Autenticação com ID do cliente e assinatura digital (plano Premium ou licença anterior)
    Ao usar um ID do cliente e uma assinatura digital para autenticar sua solicitação, você pode fazer o seguinte:
    • Adicionar o parâmetro channel às solicitações para ver relatórios de uso mais detalhados
    • Ver relatórios de uso com mais de 30 dias de dados no Console do Cloud
    • Usar as ferramentas de análise do Google Maps para a API Maps JavaScript

Veja mais informações sobre os relatórios disponíveis para clientes do plano Premium.

Autenticação usando uma chave de API

Acessar a chave de API

A chave de API é um identificador exclusivo utilizado na autenticação de solicitações associadas ao seu projeto para fins de uso e faturamento.

Para acessar uma chave de API, faça o seguinte:

  1. Na página do seletor de projetos do Console do Cloud, escolha ou crie um projeto do Google Cloud a que você quer adicionar uma chave de API.

    Acessar a página do seletor de projetos

    Observação: para ter acesso total aos recursos do plano, os clientes Premium precisam usar o projeto associado a essa conta. Ao comprar sua licença, você recebeu o nome do recurso Premium neste formato: gme-[company] > proj-[number] ([type]). Para garantir que você está acessando o projeto correto, faça login no console como proprietário usando o link console.cloud.google.com/project/number (substitua number pelo número do seu projeto). Você encontrará o proprietário do projeto na mensagem de boas-vindas.

  2. Acesse a página Plataforma Google Maps > Credenciais.

    Acessar a página "Credenciais"

  3. Na página Credenciais, clique em Criar credenciais > Chave de API.
    A caixa de diálogo Chave de API criada exibirá sua chave recém-criada.
  4. Clique em Fechar.
    A nova chave aparecerá na página Credenciais, em Chaves de API.
    Lembre-se de restringir a chave de API antes de usá-la na produção.

Adicionar a chave de API à solicitação

Você precisa incluir uma chave de API em todas as solicitações da Plataforma Google Maps. No exemplo a seguir, substitua YOUR_API_KEY pela sua chave.

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

O HTTPS é obrigatório e recomendado, respectivamente, para solicitações que usam uma chave de API e um ID do cliente. Este protocolo também é necessário para aplicativos que incluem dados confidenciais de usuários nas solicitações, como a localização.

Restringir chaves de API

Essa ação aumenta a segurança do aplicativo, garantindo que somente solicitações autorizadas sejam feitas com sua chave de API. Recomendamos que você siga as instruções para definir restrições nessas chaves. Para mais informações, consulte Práticas recomendadas de segurança da API.

Para restringir uma chave de API, faça o seguinte:

  1. Acesse a página Plataforma Google Maps > Credenciais.

    Acessar a página "Credenciais"

  2. Selecione a chave de API em que você quer definir uma restrição. A página de propriedades será exibida.
  3. Em Restrições de chave, defina as seguintes opções:
    • Restrições do aplicativo:
      1. Para aceitar solicitações da lista de endereços IP de servidores da Web que você fornece, selecione Endereços IP (servidores da Web, cron jobs etc.) na lista de Restrições do aplicativo.
      2. Especifique um endereço IPv4 ou IPv6 ou uma sub-rede usando a notação CIDR (por exemplo, 192.168.0.0/22). Se você precisar inserir outra entrada, uma nova caixa aparecerá depois que a ação anterior for concluída.
    • Restrições de API:
      1. Clique em Restringir chave.
      2. Escolha Plataforma Google Maps no menu suspenso Selecionar APIs. Se a Plataforma Google Maps não aparecer na lista, será preciso ativá-la.
  4. Para concluir as mudanças, clique em Salvar.

Autenticar usando um ID do cliente e uma assinatura digital

Após adquirir sua licença do plano Premium da Plataforma Google Maps, você receberá um e-mail de boas-vindas do Google com o ID do cliente e sua chave criptográfica privada, que poderá ser usada para gerar uma assinatura digital exclusiva.

O exemplo de código abaixo mostra os parâmetros client e signature para onde você precisa transmitir o ID do cliente e a assinatura digital exclusiva.

    https://maps.googleapis.com/maps/api/directions/json
      ?origin=Toronto
      &destination=Montreal
      &client=gme-YOUR_CLIENT_ID
      &signature=YOUR_URL_SIGNATURE
  • Substitua YOUR_CLIENT_ID pelo ID contido no e-mail de boas-vindas.

    Ele começa com os caracteres gme-.

  • Substitua SIGNATURE pela sua assinatura digital exclusiva. Confira a seção Como gerar uma assinatura digital.

Observações:

  • Uma opção é usar o parâmetro channel ao autenticar a Plataforma Google Maps com um ID do cliente e uma assinatura digital para receber relatórios de uso detalhados. Consulte a Visão geral dos relatórios no plano Premium se quiser mais informações.
  • Se você estava usando uma chave de API para autenticação e trocou por um ID do cliente, remova o parâmetro key das suas solicitações. Os serviços da Web das APIs Google Maps negarão as solicitações feitas com um ID do cliente e uma chave de API.

Gerar uma assinatura digital

As solicitações para a API Directions dos planos Premium da Plataforma Google Maps exigem uma signature digital, que pode ser gerada com a chave criptográfica privada fornecida no e-mail de boas-vindas. Consulte Saiba mais sobre sua chave criptográfica privada.

Siga as etapas abaixo se quiser gerar uma assinatura digital para sua solicitação.

  1. Gere o URL da solicitação sem a assinatura, incluindo o parâmetro client. Todos os caracteres que não forem padrão terão que ser codificados para uso em URL:

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

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

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

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

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

    Observação: o padrão Base64 modificado para URLs substitui os caracteres + e / por - e _, respectivamente, para que essas assinaturas Base64 não precisem mais ser codificadas para uso em URL.

  4. Codifique a assinatura binária resultante usando o Base64 modificado para URLs. Assim, você a converte em um formato que pode ser transmitido por URL.

  5. Anexe essa assinatura ao URL dentro de um parâmetro signature:

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

Observações:

  • A assinatura exclusiva permite que nossos servidores verifiquem se qualquer site que gera solicitações usando seu ID do cliente está autorizado a fazer isso. A assinatura também é exclusiva por URL, garantindo que as solicitações que usam seu ID não possam ser modificadas sem que uma nova assinatura seja gerada.
  • A tentativa de acessar a API Directions com uma assinatura inválida resultará em um erro HTTP 403 (proibido). Ao converter seus aplicativos para usar a assinatura de URL, teste as assinaturas para garantir que elas iniciem uma solicitação válida. Primeiro, verifique se o URL original é válido e se você gerou as assinaturas corretas.
  • Para ver exemplos de como implementar a assinatura de URL usando o código do lado do servidor, consulte Exemplo de código para assinatura de URL.

Para assinar um URL agora, insira o URL e a chave secreta de assinatura dele abaixo. O URL precisa ter o formato descrito na etapa 1 acima e ser codificado para uso em URL.

Exemplo de código para assinatura de URL

As seções a seguir mostram como implementar a assinatura de URL usando o código do lado do servidor. Os URLs precisam ser assinados do lado do servidor para evitar a exposição da sua chave criptográfica aos usuários.

Python

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

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

import hashlib
import hmac
import base64
import urllib.parse as 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, str.encode(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.decode()

if __name__ == "__main__":
    input_url = input("URL to Sign: ")
    secret = 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. Talvez as versões mais antigas precisem usar o Apache Commons ou similar. Faça o download do código (link em inglês).

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

Node JS

O exemplo abaixo usa módulos nativos do Node para assinar um URL. Faça o download do código (link em inglês).

'use strict'

const crypto = require('crypto');
const url = require('url');

/**
 * Convert from 'web safe' base64 to true base64.
 *
 * @param  {string} safeEncodedString The code you want to translate
 *                                    from a web safe form.
 * @return {string}
 */
function removeWebSafe(safeEncodedString) {
  return safeEncodedString.replace(/-/g, '+').replace(/_/g, '/');
}

/**
 * Convert from true base64 to 'web safe' base64
 *
 * @param  {string} encodedString The code you want to translate to a
 *                                web safe form.
 * @return {string}
 */
function makeWebSafe(encodedString) {
  return encodedString.replace(/\+/g, '-').replace(/\//g, '_');
}

/**
 * Takes a base64 code and decodes it.
 *
 * @param  {string} code The encoded data.
 * @return {string}
 */
function decodeBase64Hash(code) {
  // "new Buffer(...)" is deprecated. Use Buffer.from if it exists.
  return Buffer.from ? Buffer.from(code, 'base64') : new Buffer(code, 'base64');
}

/**
 * Takes a key and signs the data with it.
 *
 * @param  {string} key  Your unique secret key.
 * @param  {string} data The url to sign.
 * @return {string}
 */
function encodeBase64Hash(key, data) {
  return crypto.createHmac('sha1', key).update(data).digest('base64');
}

/**
 * Sign a URL using a secret key.
 *
 * @param  {string} path   The url you want to sign.
 * @param  {string} secret Your unique secret key.
 * @return {string}
 */
function sign(path, secret) {
  const uri = url.parse(path);
  const safeSecret = decodeBase64Hash(removeWebSafe(secret));
  const hashedSignature = makeWebSafe(encodeBase64Hash(safeSecret, uri.path));
  return url.format(uri) + '&signature=' + hashedSignature;
}

C#

No exemplo abaixo, a biblioteca padrão System.Security.Cryptography é usada para assinar uma solicitação de URL. É preciso converter a codificação Base64 padrão para implementar uma versão compatível com URL. Faça o download do código (link em inglês).

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

Você pode testar o URL e a chave privada a seguir para ver se a assinatura correta é gerada. Essa chave privada serve exclusivamente para testes e não será validada por nenhum Serviço do Google.

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

Exemplos em outras linguagens

Veja outros exemplos de linguagens no projeto url-signing.

Mais informações sobre sua chave criptográfica privada

A chave de assinatura do URL criptográfica privada será emitida com seu ID do cliente e é uma "chave secreta compartilhada" entre você e o Google. Ela é somente sua e é exclusiva para cada ID do cliente. Por isso, mantenha-a em segurança. Recomenda-se que essa chave não seja informada em solicitações, armazenada em sites nem publicada em fóruns públicos. Qualquer pessoa que tenha essa chave de assinatura pode fazer solicitações usando sua identidade.

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

Se você perdeu sua chave, faça login no Console do Cloud e clique em Maps: gerenciar ID do cliente para recuperá-la.

Solucionar problemas de autenticação

Se a sua solicitação estiver incorreta ou fornecer uma assinatura inválida, a Plataforma Google Maps retornará um erro HTTP 403 (Forbidden).

Para resolver problemas de URLs específicos, use o depurador de assinaturas de URL. Com ele, você pode validar rapidamente um URL e uma assinatura gerada pelo seu aplicativo.

Os clientes do plano Premium também podem resolver problemas de URLs específicos fazendo login no Console do Cloud e selecionando Recursos > Ferramentas on-line do plano Premium da Plataforma Google Maps > Depurador de assinaturas de URL para as APIs Web Service e Image.