Autenticación y autorización

Esta página está destinada únicamente a clientes con una licencia anterior de Maps APIs for Work o Maps API for Business. Esta página no está destinada a clientes con el nuevo Google Maps APIs Premium Plan, que se encuentra disponible desde enero de 2016.

Firmas e ID de cliente

En el caso de los clientes de Google Maps APIs for Work, las API de imagen (Static Maps API y Street View Image API) aceptan un ID de cliente y una firma exclusiva para la autenticación.

ID de cliente y firma

Cuando se usan las API de imagen con una licencia deGoogle Maps APIs for Work, se requieren dos parámetros de autenticación además de los parámetros estándares:

  • Tu ID de cliente. Para acceder a las funciones especiales de Google Maps APIs for Work, debes proporcionar un ID de cliente al acceder a cualquiera de los servicios o las bibliotecas de API. Cuando te registres para Google Maps APIs for Work, recibirás este ID de cliente del Google Cloud Support Portal. Todos los ID de cliente comienzan con un prefijo gme-. Pasa tu ID de cliente como valor del parámetro client.

  • Una firma exclusiva, generada mediante tu clave criptográfica privada. Pasa esta firma como valor del parámetro signature. A continuación, en la sección de firmas digitales, encontrarás información adicional sobre la generación de firmas.

Static Maps API:

    <img src="https://maps.googleapis.com/maps/api/staticmap
      ?center=-15.800513,-47.91378
      &zoom=11
      &size=300x300
      &client=YOUR_CLIENT_ID
      &signature=SIGNATURE">

Street View Image API:

    <img src="https://maps.googleapis.com/maps/api/streetview
      ?location=40.720032,-73.988354
      &size=400x400
      &fov=90&heading=235&pitch=10
      &client=YOUR_CLIENT_ID
      &signature=SIGNATURE">

No debes incluir un parámetro key en tu solicitud.

Firmas digitales, para clientes de Google Maps APIs for Work

Para las solicitudes a API de imagen por parte de clientes de Google Maps APIs for Work, se requiere una firma digital signature, la cual se genera con la clave criptográfica privada que te proporcionamos en tu correo electrónico de bienvenida.

El proceso de inicio de sesión usa un algoritmo de encriptación que combina una URL y una clave. La firma exclusiva obtenida permite a nuestros servidores verificar que los sitios que generen solicitudes con tu ID de cliente estén autorizados para hacerlo. La firma también es exclusiva de cada URL. De esta forma, se garantiza que las solicitudes que usen tu ID de cliente no se puedan modificar sin generar una nueva firma.

Tu clave criptográfica privada

Tu clave criptográfica privada para firmas de URL se generará con tu ID de cliente y es una “clave secreta compartida” entre tú y Google. Esta clave para firmas es solo tuya y es exclusiva de tu ID de cliente. Por esta razón, debes asegurarte de que tu clave para firmas esté protegida. Esta clave no debe pasarse en ninguna solicitud, almacenarse en sitios web ni publicarse en foros públicos. Si alguien obtiene esta clave de firma, podrá realizar solicitudes falsas con tu identidad.

Nota: Esta clave criptográfica privada para firmas no es igual a las claves de API que emite la Google API Console.

Si extraviaste tu clave criptográfica privada, accede a Google Cloud Support Portal y haz clic en Maps: Manage Client ID para recuperarla.

Genera una firma digital

Si intentas acceder a API de imagen con una firma no válida, se mostrará el error HTTP 403 (Forbidden). A medida que conviertas tus aplicaciones para que empleen firmas de URL, prueba las firmas a fin de asegurarte de que inicien una solicitud válida. Primero debes probar si la URL original es válida y si se generan las firmas correctas.

Sigue estos pasos para crear una firma digital para tu solicitud:

  1. Crea la URL de la solicitud sin la firma y asegúrate de incluir el parámetro client. Ten en cuenta que cualquier carácter no estándar deberá estar codificado para direcciones URL:

    Static Maps API: https://maps.googleapis.com/maps/api/staticmap?center=40.714%2c%20-73.998&zoom=12&size=400x400&client=clientID

    Street View Image API: https://maps.googleapis.com/maps/api/streetview?location=41.403609,2.174448&size=456x456&client=clientID

    Nota: Todos los servicios de Google deben codificarse con caracteres UTF-8 (que implícitamente incluye ASCII). Si tus aplicaciones funcionan con otros conjuntos de caracteres, asegúrate de que creen direcciones URL con caracteres UTF-8 y que los codifiquen en formato URL correctamente.

  2. Extrae la parte del dominio de la solicitud y deja solo la ruta a la consulta:

    Static Maps API: /maps/api/staticmap?center=40.714%2c%20-73.998&zoom=12&size=400x400&client=clientID

    Street View Image API: /maps/api/streetview?location=41.403609,2.174448&size=456x456&client=clientID

  3. Obtén tu clave privada, codificada en Base64 modificado para URL, y firma la URL anterior con el algoritmo HMAC-SHA1. Es posible que debas decodificar esta firma a su formato binario original. Ten en cuenta que, en la mayoría de las bibliotecas criptográficas, la firma resultante estará en formato binario.

    Nota: Base64 modificado para direcciones URL reemplaza los caracteres + y / del Base64 estándar por - y _ respectivamente, de modo que ya no es necesario codificar en formato URL las firmas Base64.

  4. Codifica la firma binaria resultante con Base64 modificado para direcciones URL para poder convertir esa firma en algo que pueda pasarse dentro de una URL.

  5. Incluye esta firma en la URL dentro del parámetro signature:

    Static Maps API:https://maps.googleapis.com/maps/api/staticmap?center=40.714%2c%20-73.998&zoom=12&size=400x400&client=clientID&signature=base64signature

    Street View Image API:https://maps.googleapis.com/maps/api/streetview?location=41.403609,2.174448&size=456x456&client=clientID&signature=base64signature

Para ver ejemplos de implementación de firmas de URL con código de servidor, consulta Ejemplo de código para firmas de URL.

Ejemplo de código para la firma de URL

En las siguientes secciones se muestra cómo implementar una firma de URL usando un código de servidor. Siempre debes firmas las URL en el servidor para evitar la exposición de tu clave criptográfica a los usuarios.

Python

El siguiente ejemplo usa bibliotecas Python estándar para firmar una URL. (Descargar el 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

El siguiente ejemplo usa la clase java.util.Base64 disponible desde JDK 1.8; las versiones anteriores podrían necesitar Apache Commons o similares (Descargar el 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#

El siguiente ejemplo usa la biblioteca predeterminada System.Security.Cryptography para firmar una solicitud de URL. Ten en cuenta que debes convertir la codificación predeterminada Base64 para implementar una versión compatible con URL. (Descargar el 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));
    }
  }
}

Solución de problemas de autenticación

Si tu solicitud no tiene el formato correcto o proporciona una firma no válida, la API de imagen muestra un error HTTP 403 (Forbidden).

Para solucionar problemas en direcciones URL individuales, puedes usar el URL Signing Debugger. Este depurador te permitirá validar rápidamente una URL y la firma que generó tu aplicación.

Como alternativa, los clientes de Google Maps APIs for Work pueden solucionar los problemas de las URL accediendo al Google Cloud Support Portal y seleccionando Resources > Google Maps APIs for Work online tools > URL Signing Debugger for Web Service and Image APIs.