Аутентификация и авторизация

Эта страница предназначена только для пользователей, которые владеют лицензией на ранее выпускавшиеся продукты Maps APIs for Work или Maps API for Business. Эта страница не предназначена для пользователей нового продукта Google Maps APIs Premium Plan, который стал доступен в январе 2016 года.

Идентификаторы клиента и подписи

При использовании веб-служб Google Maps APIs с лицензией на Google Maps APIs for Work необходимо указать два параметра аутентификации: идентификатор клиента и уникальную цифровую подпись (вместо ключа API).

Если вы переходите от использования бесплатных веб-служб API к реализации Google Maps APIs for Work, удалите параметр key из своих запросов. Веб-службы Google Maps APIs будут отклонять запросы, оформленные с использованием как идентификатора клиента, так и ключа.

Ваши идентификатор клиента и подпись

После приобретения лицензии на Google Maps APIs for Work вы получите по эл. почте приветственное письмо от Google, в котором будут указаны ваш идентификатор клиента и ваш закрытый криптографический ключ.

  • Ваш идентификатор клиента используется для доступа к специальным функциям Google Maps APIs for Work – его необходимо указывать, чтобы получить доступ к любым библиотекам или службам API. Все идентификаторы клиентов начинаются с префикса gme-. Передавайте свой идентификатор клиента в виде значения параметра client.

  • Уникальная цифровая подпись создается с использованием вашего закрытого криптографического ключа. Передавайте эту подпись в виде значения параметра signature. Дополнительную информацию о создании подписи см. ниже, в разделе с описанием цифровых подписей.

Вот пример для 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

В случае потери идентификатора клиента или закрытого криптографического ключа их можно восстановить – для этого необходимо выполнить вход в Google Cloud Support Portal и щелкнуть Maps: Manage Client ID среди ссылок в левой части страницы.

Дополнительный параметр для отчетов

Помимо параметров аутентификации, в запросах Google Maps APIs for Work можно указать следующий параметр:

  • channel используется для предоставления дополнительной отчетной информации путем раздельного группирования разных каналов по вашим отчетам. См. раздел Отчеты по каналам использования в документе для веб-служб Google Maps APIs for Work, который называется Квота и отчеты.

Цифровые подписи

Запросы к API веб-служб, выполняемые пользователями Google Maps APIs for Work, требуют наличия параметра signature – цифровой подписи, созданной с использованием криптографического ключа, который был получен по эл. почте в приветственном письме.

В процессе подписания совместно задействуются URL-адрес и ключ с использованием алгоритма шифрования. Полученная уникальная подпись позволяет нашим серверам проверять наличие соответствующих прав у сайта, который создает запросы с помощью вашего идентификатора клиента. Эта подпись также является уникальной для каждого URL-адреса, благодаря чему запросы, в которых используется ваш идентификатор, невозможно изменить без создания новой подписи.

Ваш закрытый криптографический ключ

Ваш закрытый криптографический ключ для подписи URL-адреса предоставляется вместе с вашим идентификатором клиента и является "секретным общим ключом", который используется между вами и Google. Ключ для подписи принадлежит исключительно вам и уникален для вашего идентификатора клиента. По этой причине рекомендуется не разглашать ключ для подписи посторонним лицам. Этот ключ ни в коем случае нельзя пересылать в каких-либо запросах, хранить на веб-сайтах или публиковать на общедоступных форумах. Любой, кто получит этот ключ для подписи, сможет создавать ложные запросы от вашего имени.

Примечание. Этот закрытый криптографический ключ для подписи не идентичен ключам API, которые предоставляются Google API Console.

В случае утраты закрытого криптографического ключа выполните вход в Google Cloud Support Portal и щелкните Maps: Manage Client ID, чтобы восстановить ключ.

Создание цифровой подписи

Попытка доступа к веб-службам Google Maps APIs с использованием недействительной подписи приведет к ошибке HTTP 403 (Forbidden). При преобразовании приложений в целях использования подписей для URL-адреса необходимо проверить подписи и убедиться, что с ними создается действительный запрос. В первую очередь следует проверить, является ли URL-адрес действительным, а также убедиться в правильности создаваемых подписей.

Выполните следующие действия, чтобы создать цифровую подпись для запроса.

  1. Создайте URL-адрес запроса без подписи, который обязательно должен содержать параметр client. Обратите внимание, что любые нестандартные символы в URL-адресе должны быть закодированы. Например, для Directions API создайте URL-адрес следующим образом:

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

    Примечание. Всем службам Google требуется кодировка символов в формате UTF-8 (в который неявно включен ASCII). Если в приложениях используются другие наборы символов, убедитесь, что они создают URL-адреса в формате UTF-8 и правильно кодируют их.

  2. Удалите из запроса часть с информацией о домене, оставив только путь и запрос. Например, для Directions API:

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

  3. Извлеките свой закрытый ключ, который закодирован в измененном формате Base64 для URL-адресов, и подпишите вышеупомянутый URL-адрес с помощью алгоритма HMAC-SHA1. Может потребоваться декодирование этого ключа в исходный двоичный формат. Обратите внимание, что в большинстве криптографических библиотек результирующая подпись будет иметь двоичный формат.

    Примечание. В измененном формат Base64 для URL-адресов символы + и / заменяют символы стандартного формата Base64 - и _ соответственно, поэтому подписи Base64 в URL-адресах больше не нужно кодировать.

  4. Закодируйте полученную двоичную подпись с помощью измененного формата Base64 для URL-адресов, чтобы преобразовать подпись в элемент, который можно передать в URL-адресе.

  5. Добавьте эту подпись в URL-адрес в параметре signature. Например, для Directions API:

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

Примеры, демонстрирующие способы добавления подписи URL-адреса путем кодирования на стороне сервера, см. в разделе Пример кода для подписи URL-адреса.

Пример кода для подписи URL-адреса

В следующих разделах приводится информация по добавлению подписи URL-адреса путем кодирования на стороне сервера. URL-адреса должны всегда подписываться на стороне сервера, чтобы предотвратить раскрытие криптографического ключа пользователям.

Python

В примере ниже использованы стандартные библиотеки Python для подписи URL-адресов. (Загрузить код.)

#!/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

В примере ниже используется класс java.util.Base64, который добавлен в версии JDK 1.8. Для более старых версий, возможно, потребуется использовать Apache Commons или аналогичные библиотеки. (Загрузить код.)

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#

В примере ниже использована стандартная библиотека System.Security.Cryptography для создания подписи URL-запроса. Обратите внимание, что для реализации безопасной версии URL-адреса необходимо преобразовать стандартную кодировку Base64. (Загрузить код.)

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

Для тестирования вы можете использовать следующий URL-адрес и закрытый ключ, чтобы проверить, создается ли правильная подпись. Обратите внимание, что этот закрытый ключ предназначен исключительно для тестирования и не будет принят ни одной из служб Google.

  • URL-адрес: https://maps.googleapis.com/maps/api/geocode/json?address=New+York&client=clientID
  • Закрытый ключ: vNIXE0xscrmjlyV-12Nj_BvUPaw=
  • Часть URL-адреса для подписи: /maps/api/geocode/json?address=New+York&client=clientID
  • Подпись: chaRF2hTJKOScPr-RQCEhZbSzIE=
  • Полностью подписанный URL-адрес: https://maps.googleapis.com/maps/api/geocode/json?address=New+York&client=clientID&signature=chaRF2hTJKOScPr-RQCEhZbSzIE=

Примеры на других языках

Примеры, которые включают в себя другие языки, доступны в проекте подписи URL.

Устранение неполадок, связанных с аутентификацией

Если ваш запрос искажен или имеет недопустимую подпись, API веб-служб отобразит ошибку HTTP 403 (Forbidden).

Для устранения неполадок отдельных URL-адресов можно использовать отладчик URL Signing Debugger. Он позволяет быстро выполнить проверку URL-адреса и подписи, созданных приложением.

При необходимости владельцы Google Maps APIs for Work могут устранить неполадки, связанные с отдельными URL-адресами, выполнив вход в Google Cloud Support Portal и выбрав Resources > Google Maps online tools > URL Signing Debugger for Web Service and Image APIs.