Directions API: получение ключа API

Примечание. Тарифный план Premium платформы Google Карт больше недоступен для регистрации и новых клиентов.

Выбор метода аутентификации

Чтобы использовать платформу Google Карт, необходимо выполнять аутентификацию запросов с помощью ключа API или идентификатора клиента и цифровой подписи.

Метод аутентификации зависит от типа вашей лицензии:

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

  • Аутентификация с помощью ключа API (план Premium)
    Используя ключ API для аутентификации запроса, вы можете:
    • управлять всеми API на странице API в Google Cloud Console;
    • просматривать данные об использовании в реальном времени и за последние 30 дней на странице API в Cloud Console;
    • добавлять в запросы параметр channel, чтобы просматривать отчеты с более подробной информацией об использовании;
    • просматривать отчеты об использовании более чем за 30 дней в Cloud Console.
  • Аутентификация с помощью идентификатора клиента и цифровой подписи (план Premium или прежняя лицензия)
    Используя идентификатор клиента и цифровую подпись для аутентификации запроса, вы можете:
    • добавлять в запросы параметр channel, чтобы просматривать отчеты с более подробной информацией об использовании;
    • просматривать отчеты об использовании более чем за 30 дней в Cloud Console;
    • использовать инструменты Maps Analytics для Maps JavaScript API.

Подробнее об отчетах, доступных для клиентов с планом Premium

Аутентификация с помощью ключа API

Как получить ключ API

Ключ API – это уникальный идентификатор, который используется для аутентификации запросов, связанных с вашим проектом. Этот ключ нужен для использования API и оплаты.

Чтобы получить его, выполните следующие действия:

  1. Перейдите на страницу выбора проекта в Cloud Console. Выберите существующий проект Google Cloud, для которого нужно добавить ключ API, или создайте новый.

    Перейти на страницу выбора проекта

    Примечание. Чтобы получить полный доступ ко всем функциям плана Premium, необходимо использовать проект, связанный с аккаунтом Premium. При покупке лицензии вашему объекту в рамках плана Premium присваивается название в формате gme-[company] > proj-[number] ([type]). Чтобы приступить к работе с нужным проектом, войдите как владелец проекта в консоль по адресу console.cloud.google.com/project/number (вместо number укажите номер проекта). Имя владельца проекта можно найти в приветственном письме.

  2. Откройте страницу Google Maps Platform > Credentials (Платформа Google Карт > Учетные данные).

    Перейти на страницу Credentials (Учетные данные)

  3. На странице Credentials (Учетные данные) нажмите Create credentials > API key (Создать учетные данные > Ключ API).
    Появится диалоговое окно с созданным ключом API.
  4. Нажмите Закрыть.
    Новый ключ API можно будет найти в разделе API keys (Ключи API) на странице Credentials (Учетные данные).
    Не забудьте настроить ограничения для ключа API, прежде чем использовать его в рабочей среде.

Добавление ключа API в запрос

Каждый запрос к платформе Google Карт должен содержать ключ API. Укажите свой ключ API вместо YOUR_API_KEY в следующем примере:

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

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

Настройка ограничений для ключей API

Ограничения повышают безопасность, поскольку с помощью ключа API можно будет отправлять только авторизованные запросы. Мы настоятельно рекомендуем следовать инструкциям по настройке ограничений для ключей API. Дополнительные сведения приводятся в рекомендациях по работе с ключами API.

Чтобы задать ограничение для ключа API, выполните следующие действия:

  1. Откройте страницу Google Maps Platform > Credentials (Платформа Google Карт > Учетные данные).

    Перейти на страницу Credentials (Учетные данные)

  2. Выберите нужный ключ API. Откроется страница со свойствами ключа API.
  3. В разделе Key restrictions (Ограничения для ключа) установите следующие ограничения:
    • Ограничения для приложений:
      1. Чтобы принимать запросы от IP-адресов веб-серверов, входящих в составленный вами список, выберите IP-адреса (веб-серверы, задания Cron и т. п.) в списке Допустимый тип приложений.
      2. Укажите один адрес IPv4 или IPv6 либо подсеть в формате бесклассовой адресации (например, 192.168.0.0/22). Затем можно добавить следующую запись. Для этого используйте поле, которое появится после завершения ввода предыдущей записи.
    • Ограничения для API:
      1. Нажмите Restrict key (Применить ограничения для ключа).
      2. В раскрывающемся списке Select APIs (Выберите API) нажмите Google Maps Platform (Платформа Google Карт). Если такого варианта нет, вам необходимо включить платформу Google Карт.
  4. Нажмите Save (Сохранить).

Аутентификация с помощью идентификатора клиента и цифровой подписи

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

В примере кода ниже показаны параметры client и signature, в которые нужно передать идентификатор клиента и уникальную цифровую подпись.

    https://maps.googleapis.com/maps/api/directions/json
      ?origin=Toronto
      &destination=Montreal
      &client=gme-YOUR_CLIENT_ID
      &signature=YOUR_URL_SIGNATURE
  • Укажите идентификатор клиента из приветственного письма вместо YOUR_CLIENT_ID.

    Идентификатор начинается с символов gme-.

  • Укажите уникальную цифровую подпись вместо SIGNATURE (см. Как создать цифровую подпись).

Примечания

  • Чтобы получать отчеты с более подробной информацией об использовании, вы также можете использовать параметр channel при аутентификации в платформе Google Карт с помощью идентификатора клиента и цифровой подписи. Подробные сведения об этом доступны в разделе Обзор отчетов плана Premium.
  • Если ранее для аутентификации вы использовали ключ API и теперь переходите к использованию идентификатора клиента, удалите параметр key из своих запросов. Веб-сервисы Google Maps API будут отклонять запросы, которые одновременно содержат и идентификатор клиента, и ключ API.

Как создать цифровую подпись

Чтобы клиенты платформы Google Карт с тарифным планом Premium могли отправлять запросы в Directions API, им требуется цифровая подпись (signature), которую вы можете создать с помощью закрытого криптографического ключа, отправленного вам в приветственном письме (см. Подробная информация о вашем закрытом криптографическом ключе).

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

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

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

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

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

    /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:

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

Примечания

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

Чтобы подписать URL прямо сейчас, укажите URL и секрет для подписи URL ниже. URL должен иметь формат, который описан на шаге 1 выше, и быть надлежащим образом закодирован.

Образец кода для подписи 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 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

В примере ниже используется класс 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;
  }
}

Node.js

В примере ниже для подписи URL использованы оригинальные модули Node. Скачать код можно здесь.

'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#

В примере ниже для подписи URL использована библиотека System.Security.Cryptography по умолчанию. Обратите внимание, что для реализации безопасной версии 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.

Подробная информация о вашем закрытом криптографическом ключе

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

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

Если вы потеряли закрытый криптографический ключ, его можно восстановить. Для этого войдите в Cloud Console и нажмите Карты: управление идентификатором клиента.

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

Если ваш запрос имеет неверный формат или недопустимую подпись, платформа Google Карт вернет ошибку HTTP 403 (Forbidden).

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

Кроме того, клиенты с планом Premium могут устранить неполадки, связанные с отдельными URL, в Cloud Console. Для этого нужно выбрать Resources > Google Maps Platform Premium Plan online tools > URL Signing Debugger for Web Service and Image APIs (Ресурсы > Онлайн-инструменты плана Premium платформы Google Карт > URL Signing Debugger для API веб-сервисов и изображений).