API-ключ в Google Maps JavaScript API служит идентификатором проекта и используется для авторизации запросов к сервисам Google Maps Platform. По умолчанию любой, кто получил доступ к ключу, может попытаться использовать его для выполнения запросов от имени владельца проекта. Это создает риски:
Для снижения этих рисков Google предоставляет механизм ограничений (Restrictions), позволяющий привязать ключ к определенным источникам запросов. Наиболее распространенными являются:
Правильная настройка ограничений считается обязательной практикой безопасности при работе с Google Maps Platform.
В настройках Google Cloud Console для каждого ключа можно выбрать один из вариантов ограничения источника запросов:
| Тип ограничения | Назначение |
|---|---|
| None | Отсутствие ограничений |
| HTTP Referrers | Ограничение по доменам и страницам сайта |
| IP Addresses | Ограничение по IP-адресам серверов |
| Android Apps | Ограничение по приложениям Android |
| iOS Apps | Ограничение по приложениям iOS |
Для Google Maps JavaScript API обычно применяется ограничение по HTTP Referrer, поскольку библиотека работает непосредственно в браузере пользователя.
Когда браузер загружает Google Maps JavaScript API, вместе с запросом передается HTTP-заголовок Referer. Он содержит адрес страницы, с которой выполняется загрузка.
Пример:
https://example.com/map.html
Google сравнивает значение Referer с настройками ключа.
Если домен разрешен, API загружается успешно.
Если домен отсутствует в списке разрешенных источников, появляется ошибка авторизации.
Ограничения по домену используются для:
Практически любой проект, использующий Google Maps JavaScript API в браузере, должен использовать именно этот тип ограничения.
После создания API-ключа в Google Cloud Console необходимо:
Примеры записей:
https://example.com/*
https://www.example.com/*
https://app.example.com/*
https://*.example.com/*
После сохранения изменений Google начинает применять ограничения к запросам.
Для упрощения настройки допускается использование символа
*.
https://example.com/*
Разрешены:
https://example.com/
https://example.com/map
https://example.com/contact
https://*.example.com/*
Разрешены:
https://app.example.com
https://crm.example.com
https://maps.example.com
https://*.example.com/*
Подходит также для:
https://dev.crm.example.com
https://api.dev.example.com
В некоторых случаях можно ограничить использование ключа отдельным разделом сайта.
Пример:
https://example.com/maps/*
Допустимые URL:
https://example.com/maps
https://example.com/maps/store
https://example.com/maps/search
Недопустимые URL:
https://example.com/catalog
https://example.com/blog
Подобный подход применяется редко, поскольку усложняет поддержку проекта.
Во время разработки карты часто запускаются на локальном компьютере.
Для localhost необходимо явно добавить адрес:
http://localhost/*
или
http://localhost:3000/*
Для различных инструментов разработки:
http://localhost:5173/*
http://localhost:8080/*
http://127.0.0.1/*
Без соответствующего разрешения карта не загрузится.
Разрешен только:
https://example.com/*
Но сайт открывается как:
https://www.example.com
Для Google это разные источники.
Необходимо добавить обе записи:
https://example.com/*
https://www.example.com/*
Разрешено:
http://example.com/*
Фактический сайт работает через:
https://example.com/*
Google не считает такие адреса одинаковыми.
Разрешено:
https://example.com/*
Но карта загружается с:
https://app.example.com
Требуется отдельное разрешение.
После изменения ограничений обновление применяется не мгновенно.
Иногда требуется:
При неправильной настройке часто появляются ошибки вида:
RefererNotAllowedMapError
или
Google Maps JavaScript API error: RefererNotAllowedMapError
Это означает, что текущий домен отсутствует среди разрешенных источников.
Для диагностики полезно открыть вкладку Network в инструментах разработчика браузера.
Запрос загрузки API выглядит примерно так:
https://maps.googleapis.com/maps/api/js?key=API_KEY
В его заголовках можно увидеть:
Referer: https://example.com/page
Именно это значение сравнивается с настройками ограничения.
Ограничения по IP используются для серверных приложений.
Google проверяет IP-адрес источника запроса и разрешает доступ только указанным адресам.
Пример разрешенного адреса:
203.0.113.15
Если запрос приходит с другого IP, доступ отклоняется.
Ограничения по IP подходят для:
Google Maps JavaScript API работает в браузере пользователя.
Запросы выполняются не с сервера разработчика, а с компьютеров посетителей сайта.
Следовательно:
Поэтому для JavaScript API рекомендуется использовать ограничения по домену, а не по IP.
Предположим, сайт использует Google Maps JavaScript API:
<script
src="https://maps.googleapis.com/maps/api/js?key=API_KEY">
</script>
Для ключа задано ограничение:
198.51.100.10
Этот IP принадлежит серверу.
Однако карту открывает пользователь с адресом:
85.124.10.44
Проверка завершается ошибкой, поскольку запрос исходит не с серверного IP.
Распространенная практика — разделение ключей.
Ограничения:
HTTP Referrer Restrictions
Разрешенные домены:
https://example.com/*
Используется для:
Ограничения:
IP Address Restrictions
Разрешенные IP:
203.0.113.15
203.0.113.16
Используется для:
Такой подход существенно повышает безопасность проекта.
Помимо ограничения источника запросов существует ограничение по набору доступных API.
В разделе API Restrictions можно указать, какие сервисы разрешено использовать через данный ключ.
Например:
Maps JavaScript API
или
Maps JavaScript API
Places API
Если злоумышленник получит ключ, он не сможет использовать его для других сервисов платформы.
Ключ используется только для отображения карт на сайте.
HTTP Referrer Restrictions
Разрешенные адреса:
https://example.com/*
https://www.example.com/*
https://*.example.com/*
Разрешено:
Maps JavaScript API
Запрещено:
Geocoding API
Directions API
Distance Matrix API
Roads API
В результате ключ может использоваться исключительно для загрузки карт на доверенных доменах.
Для каждого окружения желательно создавать собственный ключ:
Это позволяет быстро отзывать доступ и отслеживать использование.
Следует предоставлять только те права, которые действительно необходимы.
Нежелательно использовать настройки:
None
или
Don't restrict key
Даже временно такие конфигурации могут привести к несанкционированному использованию.
Необходимо периодически проверять:
Подобный аудит помогает своевременно обнаруживать утечки и ошибки конфигурации.
Наиболее безопасной считается схема:
| Назначение | Тип ограничения |
|---|---|
| Google Maps JavaScript API | Домен |
| Geocoding API на сервере | IP |
| Places API на сервере | IP |
| Внутренние сервисы | IP |
Разделение ключей снижает последствия компрометации одного из компонентов системы.
При возникновении ошибок рекомендуется проверить:
Последовательная проверка этих пунктов позволяет устранить большинство проблем, связанных с ограничениями API-ключей Google Maps JavaScript API.