Используйте App Check для защиты ключа API Javascript Карт

1. Прежде чем начать

Страница, демонстрирующая работающее приложение

Что вы построите.

В этой лабораторной работе вы будете использовать App Check для добавления еще одного уровня защиты к вашему ключу API, используемому в веб-среде.

В частности, в ходе Codelab будут выполнены следующие шаги для объединения всех функций:

  • Создайте веб-страницу для размещения карты с использованием API Javascript платформы Google Карт.
  • Разместите страницу на хостинге, чтобы к ней можно было получить доступ в Интернете.
  • Ограничьте домены и API, которые могут использовать API с помощью Cloud Console.
  • Добавьте и инициализируйте библиотеку App Check через Firebase.
  • Добавьте поставщика аттестации для проверки действительности заявок.
  • Обеспечьте принудительную проверку вашего приложения и монитора.

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

2. Предпосылки

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

Firebase — обеспечивает работу служб, проверяющих, что ключи API ссылаются на соответствующие домены. Также обеспечивается функциональность хостинга и развёртывания с помощью Firebase Studio.

reCAPTCHA — обеспечивает функциональность для проверки того, используют ли приложение люди, а также предоставляет открытый и закрытый ключи для подключения Firebase к домену клиентского приложения.

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

Как все это функционирует вместе, можно увидеть на следующей архитектурной схеме:

Обзор архитектуры системы

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

Это осуществляется с помощью App Check SDK, предоставляемого Firebase. Он проверяет корректность вызывающего приложения и затем предоставляет приложению токен, с помощью которого выполняются последующие вызовы API JavaScript платформы Google Карт. В свою очередь, API JavaScript платформы Google Карт проверяет корректность предоставленного токена в Firebase, чтобы убедиться, что он исходит как с правильного домена, так и через поставщика подтверждения от действительного пользователя.

Более подробную информацию об использовании App Check и Maps JavaScript API можно найти по следующему адресу, а также вам следует ознакомиться с необходимыми шагами.

https://developers.google.com/maps/documentation/javascript/maps-app-check

3. Приступайте к настройке

Если у вас ещё нет учётной записи Google Cloud, вам потребуется её создать и включить платёжные функции. Следуйте инструкциям, чтобы создать учётную запись перед началом работы.

Настройте платформу Google Карт

Если у вас еще нет учетной записи Google Cloud Platform и проекта с включенным выставлением счетов, ознакомьтесь с руководством « Начало работы с Google Maps Platform», чтобы создать учетную запись для выставления счетов и проект.

  1. В Cloud Console щелкните раскрывающееся меню проектов и выберите проект, который вы хотите использовать для этой кодовой лаборатории.

  1. Включите API и SDK платформы Google Карт, необходимые для этой лабораторной работы, в Google Cloud Marketplace . Для этого следуйте инструкциям в этом видео или в этой документации .
  2. Сгенерируйте ключ API на странице «Учётные данные» в Cloud Console. Вы можете следовать инструкциям в этом видео или в этой документации . Для всех запросов к платформе Google Карт требуется ключ API.

Другие требования для этой лабораторной работы

Для выполнения этой лабораторной работы вам понадобятся следующие учетные записи, сервисы и инструменты:

  • Базовые знания JavaScript, HTML и CSS
  • Учетная запись Google Cloud с включенным биллингом (как уже упоминалось)
  • Ключ API платформы Google Карт с включенным API JavaScript Карт (это будет сделано во время кодовой лаборатории).
  • Базовые знания о веб-хостинге и развёртывании (вы получите необходимые знания в ходе практического занятия). Работа будет осуществляться с помощью консоли Firebase и Firebase Studio.
  • Веб-браузер для просмотра файлов во время работы.

4. Создайте страницу в Firebase Studio.

Эта лабораторная работа не предполагает наличия готового приложения. Она использует Firebase Studio для создания страницы, на которой будет размещено приложение Map, и её развертывания в Firebase для тестирования. Если у вас есть существующее приложение, вы можете использовать его, изменив соответствующие домены хоста, фрагменты кода и ключи API для обеспечения корректной реализации.

Перейдите в Firebase Studio (требуется учетная запись Google) и создайте новое простое HTML- приложение. Возможно, вам придется нажать кнопку «Просмотреть все шаблоны», чтобы отобразить эту опцию, или просто нажать эту ссылку для прямого доступа.

Изображение простого HTML-шаблона

Дайте рабочему пространству подходящее имя, например, myappcheck-map (плюс случайное число для уникальности, оно будет добавлено автоматически). После этого Firebase Studio создаст рабочее пространство.

Изображение, демонстрирующее новые параметры рабочего пространства

После того, как вы ввели имя, нажмите кнопку «Создать», и начнется процесс создания проекта.

Изображение, показывающее диалоговое окно создания проекта

После создания вы можете заменить текст в файле index.html следующим кодом, который создаст страницу с картой.

<!doctype html>
<html>

<head>
 <title>Secure Map</title>
 <style>
   #map {
     height: 100%;
   }

   html,
   body {
     height: 100%;
     margin: 0;
     padding: 0;
     font-family: Arial, Helvetica, sans-serif;
   }
 </style>
</head>

<body>
 <h3>App Check Security Demo</h3>
 <!--The div element for the map -->
 <div id="map"></div>
 <script>
   (g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })({
     key: "YOUR_API_KEY",
     v: "weekly",
     // Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
     // Add other bootstrap parameters as needed, using camel case.
   });
 </script>
 <script>
   let map;
   async function initMap() {
     const { Map } = await google.maps.importLibrary("maps");
     map = new Map(document.getElementById("map"), {
       center: { lat: 51.5208, lng: -0.0977 },
       zoom: 17,
     });
   }
   initMap();
 </script>
</body>

</html>

При запуске должна появиться страница с картой работающего приложения, как показано на изображении, но!

На изображении показано работающее приложение.

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

Изображение, показывающее уведомление «Что-то пошло не так».

Фактическое сообщение об ошибке можно увидеть в веб-консоли Firebase Studio.

Сообщение об ошибке «Неверный ключ».

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

Одним из методов защиты является использование ограничений для приложений, накладываемых либо на тип используемого приложения, либо на домен или IP-адрес, с которого осуществляется вызов. Подробнее о передовых практиках можно узнать на следующем сайте:

https://developers.google.com/maps/api-security-best-practices#rec-best-practices

или с помощью прямых вызовов из командной строки или сервера, приложений, которые сами по себе не имеют возможности предоставить ссылку или отслеживаться, поэтому являются потенциальной уязвимостью в системе безопасности.

5. Создайте приложение Firebase

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

  • Запросы исходят из вашего подлинного приложения
  • Запросы поступают с аутентичного, нетронутого устройства и сеанса пользователя.

В этой лабораторной работе в качестве поставщика данной аттестации будет использоваться reCAPTCHA v3.

Создайте приложение Firebase и разместите его.

Перейдите по адресу https://firebase.google.com/ и создайте новый проект Firebase по ссылке «Перейти в консоль» .

Изображение, показывающее ссылку на консоль

Создайте новый проект, щелкнув следующую область.

Создать новый проект Firebase.

Выберите имя для проекта, например , «My App Check Project» . Оно не обязательно должно совпадать с тем, что использовалось ранее, так как приведено только для справки. Фактическое имя проекта можно отредактировать прямо под текстом. Оно будет составлено из введенного вами имени и, если оно не уникально, к нему будет добавлен номер.

Изображение, показывающее информацию для ввода названия проекта.

Если вам будет предложено добавить в приложение другие службы (например, Google Analytics), вы можете принять их или нет, но для этой лабораторной работы они не нужны, поэтому их можно не добавлять.

Нажмите кнопку «Создать проект» и дождитесь его создания. По завершении вы получите уведомление.

На изображении показано диалоговое окно создания проекта.

Когда все будет готово, нажмите «Продолжить», чтобы начать взаимодействие с проектом.

На изображении показано диалоговое окно завершения проекта.

На главной странице вы можете начать работу, добавив Firebase в свое приложение и выбрав опцию «Веб».

Начните с добавления.

Выберите настройку хостинга Firebase на своем сайте, чтобы файлы после развертывания размещались на определенном месте (для своего сайта вы можете использовать собственный вариант, но для выполнения этой практической работы вам нужно будет выполнить развертывание на хостинге Firebase).

Зарегистрируйте новое приложение.

Нажмите «Зарегистрировать приложение», чтобы создать приложение. Далее вам нужно будет использовать созданный скрипт для ссылки на проект в Firebase из нашего веб-приложения.

Код конфигурации Firebase на следующей вкладке будет использоваться в приложении для соединения Firebase и API карт, поэтому его стоит скопировать из раздела «Использование тега скрипта» и вставить в файл index.html проекта.

Тег скрипта для включения на страницу.

Нажмите «Далее», чтобы перейти к другим разделам, а затем просмотрите созданное приложение в разделе настроек проекта на сайте.

Если вам потребуется вернуться и найти подробную информацию о конфигурации позднее, вы также можете найти информацию о приложении, нажав кнопку «Настройки», как показано ниже:

Пункт меню «Настройки проекта».

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

Перейдите в раздел хостинга из ярлыков проекта или меню «Сборка» слева.

На изображении показан ярлык хостинга. или Изображение, показывающее меню сборки хостинга.

В разделе «Домен» найдите домен, созданный для приложения. Возможно, вам придётся пройти несколько шагов, чтобы настроить его, если это ещё не сделано.

На изображении показано диалоговое окно выбора домена хостинга.

6. Безопасные ключи API

Перейдите в Cloud Console в той же учетной записи, в которой вы используете Firebase, чтобы просмотреть созданный проект.

связь

Изображение, показывающее ссылку на облачную консоль

Если у вас несколько проектов, вам может потребоваться использовать раскрывающийся список или поле поиска, чтобы выбрать нужный, указав имя вашего проекта Firebase.

Изображение, показывающее список выбранных проектов

Откроется только что созданный проект. Теперь вам нужно добавить в него API Javascript для Карт, чтобы его можно было использовать внутри проекта, в том числе ограничив его использование определённым ключом API и доменом хостинга.

На изображении показана приветственная страница проекта.

Чтобы включить API Карт в проекте, используйте меню слева. Выберите пункт «API и службы», а затем «Включенные API и службы».

На изображении показано, как использовать меню «Включить API».

Выберите опцию «ВКЛЮЧИТЬ API И СЕРВИСЫ»

На изображении показано меню «Выбрать включить API».

Введите «Maps Javascript API» в поле поиска.

Изображение, показывающее поле поиска API

Выберите соответствующий результат.

Изображение, показывающее поле «Выбрать соответствующий API»

Затем нажмите «Включить» на API, чтобы добавить его в свой проект (это могло быть уже сделано, если вы использовали этот проект ранее).

Изображение, показывающее поле «Включить сопоставленный API»

После включения вы сможете добавить ключ API и ограничить его, но на данный момент этот шаг будет пропущен.

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

Изображение, демонстрирующее ограничивающие API.

Добавьте Maps JavaScript API в одно из ограничений API.

Выберите Maps API для фильтрации.

Для ключей в работающем приложении также следует установить ограничение на домен, на котором размещалось приложение. Сделайте это сейчас, используя домен, созданный в Firebase. Также следует добавить /* в конец имени домена, чтобы убедиться, что оно охватывает все пути в нём.

Домен для ограничения.

Более подробную информацию об ограничении ключей API можно найти по следующему адресу.

https://developers.google.com/maps/api-security-best-practices#restricting-api-keys

7. Создайте секреты reCAPTCHA

Следующим шагом будет создание проекта reCAPTCHA для предоставления аттестации и ключей как для клиента, так и для сервера.

Перейдите на сайт reCAPTCHA по адресу https://www.google.com/recaptcha/ и нажмите кнопку «Начать».

Изображение, показывающее начало работы с reCAPTCHA.

Затем зарегистрируйте новый сайт и убедитесь, что вы указали правильный домен для ограничения.

Изображение, показывающее регистрацию сайта reCAPTCHA.

Также убедитесь, что вы выбрали тот же проект Google Cloud, который создал Firebase, если у вас их несколько.

Это создаст два ключа: секретный ключ, который вы введете в консоль Firebase (его ни в коем случае нельзя помещать на страницу или в приложение, которые можно просматривать публично), и ключ сайта, который будет использоваться в веб-приложении.

Изображение страницы ключей reCAPTCHA.

Оставьте эту страницу открытой — она вам понадобится. Нажмите кнопку «Копировать секретный ключ» и вернитесь на сайт Firebase.

8. Добавьте reCAPTCHA в Firebase

В консоли администратора Firebase перейдите в меню слева. В пункте меню «Сборка» выберите «Проверка приложения».

Изображение, показывающее меню сборки хостинга.

Список услуг не может быть включен, пока не будет зарегистрировано приложение (оно было создано ранее при добавлении хостинга на сайт), нажмите «Начать», если вам нужно это настроить.

Нажмите вкладку «Приложение» и откройте веб-приложение, затем введите секрет, скопированный с сайта reCAPTCHA, и нажмите «Сохранить».

Изображение, показывающее вход в секрет

Теперь поставщик reCAPTCHA должен отметить это зелёной галочкой. Теперь это веб-приложение может использовать reCAPTCHA для подтверждения того, что пользователь или сайт правильно вызывает службу.

Зеленая галочка означает, что reCAPTCHA включена

На вкладке API теперь должно отображаться, что API платформы Google Карт активен, но в настоящее время не применяется принудительно.

Проверка приложений активна, но не применяется.

Теперь вы связали секрет reCAPTCHA с проектом Firebase и можете добавить код на веб-страницу, чтобы сопоставить ключ сайта с нужным поставщиком для использования с приложением «Карты».

reCAPTCHA проверяет ключ сайта на соответствие секретному ключу, после чего подтверждается правильность вызывающей страницы, а App Check предоставляет токен, который можно использовать при последующих вызовах Maps Javascript API. Без этого подтверждения токен не будет предоставлен, и запросы не смогут быть проверены.

9. Добавьте проверку на страницу и разверните.

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

Его можно найти в боковом меню консоли, в боковом меню API и службы, в опции Учетные данные.

Изображение, показывающее меню «Учетные данные».

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

Изображение, демонстрирующее существующую опцию ключа браузера.

Нажмите кнопку «Показать ключ» и скопируйте ключ из отобразившегося диалогового окна.

Вернитесь к проекту Firebase Studio, где ранее была открыта созданная вами HTML-страница. Теперь вы можете добавить ключ API на страницу, чтобы API Карт работало там, где на странице указан ключ "YOUR_API_KEY".

Обновите ключ API

При повторном открытии страницы будет выведено другое сообщение об ошибке.

Сообщение об ошибке «Referrer not allowed»

Это означает, что домен разработки, на котором вы размещаете страницу, не разрешён (мы добавили только развёрнутый домен). Нам потребуется опубликовать этот сайт на правильном домене, используя хостинг Firebase. Подробнее см. по ссылке:

Развертывание с помощью хостинга Firebase

и это видео

Создавайте, тестируйте и развертывайте веб-приложения Firebase быстрее в Project IDX

Ошибка «Выставление счетов не включено».

Более подробную информацию можно найти в разделе «Ошибки загрузки карт» на сайте Maps Javascript API.

Если у вас возникла ошибка RefererNotAllowedMapError, вы можете исправить ее, развернув страницу на правильном домене.

Вернитесь в Firebase Studio и нажмите значок «Firebase Studio» (он может находиться слева или справа в зависимости от настроенных вами опций), чтобы открыть параметры хостинга.

На изображении показан значок студии Firebase.

В этой лабораторной работе вам далее потребуется «Разместить приложение в Firebase», чтобы подключить экземпляр Firebase к приложению Studio.

Хост с опцией Firebase.

Затем нажмите «Аутентифицировать Firebase» , чтобы начать процесс аутентификации. Это позволит вашей учетной записи автоматизировать хостинг с помощью бэкэнда из студии.

На изображении показана опция аутентификации Firebase.

Следуйте инструкциям в командном окне, чтобы авторизовать развертывание.

Изображение, показывающее инструкции по аутентификации.

Следуйте инструкциям на экране (включая открытие нового окна), скопируйте код авторизации по запросу и вставьте его в командное окно в Firebase Studio.

Изображение, показывающее код авторизации Firebase.

Более подробную информацию об этом процессе можно получить по следующему адресу:

https://firebase.google.com/docs/studio/deploy-app

После этого вы можете нажать кнопку «Инициализировать хостинг Firebase», чтобы связать проект с проектом Firebase.

Выберите «Использовать существующий проект» и выберите проект, созданный в предыдущем разделе. Примите остальные значения по умолчанию (ваш пример может отличаться в зависимости от имени, выбранного вами при настройке проекта).

Настройка проекта хостинга Firebase.

Вернитесь в окно проводника и замените созданный файл index.html в публичном каталоге тем, который у вас уже был в корневом каталоге.

Изображение, показывающее структуру файла хостинга.

Теперь вы можете вернуться на боковую панель Firebase Studio и развернуть сайт в рабочей среде.

На рисунке показано развертывание в производстве.

Это отобразит этапы развертывания в консоли.

Изображение, показывающее этапы развертывания.

Откройте развернутый сайт, используя указанный «URL-адрес хостинга» (здесь он указан как https://my-app-check-project.web.app/, но для вашего проекта он будет другим).

Теперь приложение будет отображать карту на странице, поскольку API работают для используемых доменов.

Изображение, показывающее меню сборки хостинга.

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

10. Безопасная страница

Хотя текущая страница защищает API-ключ от домена, она не добавляет этап аттестации, чтобы убедиться, что он используется правильным приложением и пользователем. Ключ всё равно может быть украден и использован злоумышленником. Чтобы предотвратить это, необходимо добавить на страницу конфигурацию Firebase, поставщика и ключ сайта для получения корректного токена для клиента.

Вы также можете видеть, что использование Maps API отслеживается в Firebase. Поскольку не используются корректные токены, запросы выполняются непроверенными.

Необходимые данные для подключения можно получить в проекте Firebase.

Получите данные о Firebase из консоли, содержащей данные конфигурации Firebase. Перейдите на страницу настроек проекта в разделе Firebase и в разделе CDN приложения найдите раздел кода для настройки CDN (самый простой вариант).

В проекте Firebase выберите шестеренку, чтобы отобразить настройки проекта.

Изображение, демонстрирующее настройки проекта Firebase

Откроется следующая страница, содержащая подробную информацию в общем разделе под вашими приложениями.

Параметры конфигурации приложения Firebase.

Скопируйте этот код на страницу Firebase Studio ( public/index.html ), где размещена карта. Это будет выглядеть примерно так (с вашими данными, а не с данными из этого файла):

<!doctype html>
<html>

<head>
 <title>Secure Map</title>
 <style>
   #map {
     height: 100%;
   }

   html,
   body {
     height: 100%;
     margin: 0;
     padding: 0;
     font-family: Arial, Helvetica, sans-serif;
   }
 </style>
</head>

<body>
 <h3>App Check Security Demo</h3>
 <!--The div element for the map -->
 <div id="map"></div>
 <script>
   (g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })({
     key: "YOUR_API_KEY",
     v: "weekly",
     // Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
     // Add other bootstrap parameters as needed, using camel case.
   });
 </script>
 <script type="module">
   // Import the functions you need from the SDKs you need
   import { initializeApp } from "https://www.gstatic.com/firebasejs/12.2.1/firebase-app.js";

   const firebaseConfig = {
     apiKey: "YOUR_API_KEY",
     authDomain: "appcheck-map.firebaseapp.com",
     projectId: "appcheck-map",
     storageBucket: "appcheck-map.firebasestorage.app",
     messagingSenderId: "YOUR_SENDER_KEY",
     appId: "YOUR_APP_ID"
   };
    // Initialize Firebase
   const app = initializeApp(firebaseConfig);

   let map;
   async function initMap() {
     const { Map } = await google.maps.importLibrary("maps");
     map = new Map(document.getElementById("map"), {
       center: { lat: 51.5208, lng: -0.0977 },
       zoom: 17,
     });
   }
   initMap();
 </script>
</body>

</html>

Теперь Firebase добавлен в наше приложение, вызовы библиотеки reCAPTCHA выполняются с использованием предоставленного вами ключа сайта, который вы получили ранее с сайта reCAPTCHA (ранее).

Изображение, демонстрирующее ввод ключа сайта reCAPTCHA.

Более подробную информацию о добавлении этих разделов можно найти на следующей странице документации по Картам:

https://developers.google.com/maps/documentation/javascript/maps-app-check

Добавьте библиотеку App Check на страницу, затем загрузите функции для инициализации проверки приложения с помощью конфигурации Firebase и получите токен с помощью ReCaptchaV3Provider.

Сначала импортируйте библиотеку App Check:

       import {
           getToken,
           initializeAppCheck,
           ReCaptchaV3Provider,
       } from "https://www.gstatic.com/firebasejs/12.2.1/firebase-app-check.js";

Затем вы добавляете код для инициализации App Check с конфигурацией Firebase и поставщиком reCAPTCHA, используя токен сайта.

       // Get App Check Token
       const appCheck = initializeAppCheck(app, {
           provider: new ReCaptchaV3Provider('<INSERT SITE KEY>'),
           isTokenAutoRefreshEnabled: true,
       });

Наконец, добавьте функцию к элементу управления картой, используя функцию настроек библиотеки Maps Core, для получения токена. Это позволит запрашивать токены в соответствии с требованиями элемента управления картой, в зависимости от срока действия токена.

       const { Settings } = await google.maps.importLibrary('core');
     Settings.getInstance().fetchAppCheckToken = () =>
           getToken(appCheck, /* forceRefresh = */ false);

Полный файл выглядит следующим образом:

<!doctype html>
<html>

<head>
 <title>Secure Map</title>
 <style>
   #map {
     height: 100%;
   }

   html,
   body {
     height: 100%;
     margin: 0;
     padding: 0;
     font-family: Arial, Helvetica, sans-serif;
   }
 </style>
</head>

<body>
 <h3>App Check Security Demo</h3>
 <!--The div element for the map -->
 <div id="map"></div>
 <script>
   (g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })({
     key: "YOUR_API_KEY",
     v: "weekly",
     // Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
     // Add other bootstrap parameters as needed, using camel case.
   });
 </script>
 <script type="module">
   import { initializeApp } from "https://www.gstatic.com/firebasejs/12.2.1/firebase-app.js";

   import {
     getToken,
     initializeAppCheck,
     ReCaptchaV3Provider,
   } from "https://www.gstatic.com/firebasejs/12.2.1/firebase-app-check.js";

   const firebaseConfig = {
     apiKey: "YOUR_API_KEY",
     authDomain: "appcheck-map.firebaseapp.com",
     projectId: "appcheck-map",
     storageBucket: "appcheck-map.firebasestorage.app",
     messagingSenderId: "YOUR_SENDER_KEY",
     appId: "YOUR_APP_ID"
   };

   // Initialize Firebase
   const app = initializeApp(firebaseConfig);

   // Get App Check Token
   const appCheck = initializeAppCheck(app, {
     provider: new ReCaptchaV3Provider('<INSERT SITE KEY>'),
     isTokenAutoRefreshEnabled: true,
   });

   let map;
   async function initMap() {
     const { Map } = await google.maps.importLibrary("maps");

     const { Settings } = await google.maps.importLibrary('core');
     Settings.getInstance().fetchAppCheckToken = () =>
       getToken(appCheck, /* forceRefresh = */ false);

     map = new Map(document.getElementById("map"), {
       center: { lat: 51.5208, lng: -0.0977 },
       zoom: 17,
     });
   }
   initMap();
 </script>
</body>

</html>

Разверните его на сайте Firebase с помощью Firebase Studio и запустите страницу.

11. Обеспечить контроль

Теперь страница настроена, и при её запуске вы увидите, что она проверяется. Вернитесь в консоль Firebase и снова откройте раздел «Проверка приложений». Теперь проверка приложений должна отслеживать работу Maps Javascript API.

Проверка мониторинга включена.

При открытии окна теперь будет видно, что клиенты отправляют запросы и что аттестация проходит успешно (это показано на графике тёмно-синими «проверенными» запросами). Остальные запросы будут отображать вызовы, относящиеся к этапу разработки, до завершения аттестации.

График, показывающий проверенные запросы.

Теперь, когда видно, что клиенты работают, можно включить принудительное применение на сайте, чтобы гарантировать невозможность использования ключей API из недействительного клиентского приложения. Нажмите кнопку «Применить», чтобы начать принудительное применение.

Изображение кнопки принудительного применения.

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

На изображении показан диалог, регулирующий соблюдение правил.

Применение может занять некоторое время. Это отображается на экране. Если вы сразу же проверите применение, оно может не успеть распространиться.

15 минут на приведение в исполнение.

При запросе страницы вы должны увидеть, что она работает как и прежде, на самом деле на сайте ничего не изменилось.

Теперь со временем вы должны увидеть увеличение количества проверенных запросов в консоли, как показано здесь:

График, показывающий рост числа запросов на проверку.

Вы можете проверить работоспособность, вернувшись к исходному примеру в кодлабе и создав новую страницу без функции проверки приложения. Назовите эту страницу, например, nocheck.html, и разместите её в общей папке в том же месте, где находится index.html.

<!doctype html>
<html>

<head>
 <title>Secure Map</title>
 <style>
   #map {
     height: 100%;
   }

   html,
   body {
     height: 100%;
     margin: 0;
     padding: 0;
     font-family: Arial, Helvetica, sans-serif;
   }
 </style>
</head>

<body>
 <h3>App Check Security Demo</h3>
 <!--The div element for the map -->
 <div id="map"></div>
 <script>
   (g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })({
     key: "YOUR_API_KEY",
     v: "weekly",
     // Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
     // Add other bootstrap parameters as needed, using camel case.
   });
 </script>
 <script>
   let map;
   async function initMap() {
     const { Map } = await google.maps.importLibrary("maps");
     map = new Map(document.getElementById("map"), {
       center: { lat: 51.5208, lng: -0.0977 },
       zoom: 17,
     });
   }
   initMap();
 </script>
</body>

</html>

После того как вы это сделаете и введете правильный ключ API, при запросе страницы (используйте yourdomain/nocheck.html) у вас должно появиться следующее серое поле с ошибкой.

Произошла ошибка.

Проверяя консоль, вы должны увидеть сообщение об ошибке, подобное следующему:

Сообщение об ошибке «Неверная проверка приложения»

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

12. Поздравляем!

Поздравляем, вы успешно включили проверку приложений на своем сайте!

Страница, демонстрирующая работающее приложение

Вы успешно создали приложение, которое использует Firebase App Check, чтобы убедиться, что запросы поступают из допустимого домена и от действительного пользователя.

Что вы узнали

  • Как использовать Firebase Studio для размещения и развертывания веб-страницы.
  • Как использовать Cloud Console для включения и защиты API платформы Google Карт.
  • Как использовать reCAPTURE для генерации ключей, которые можно использовать для подтверждения вызовов.
  • Как использовать Firebase App Check и интегрировать его в Maps JavaScript API.
  • Узнайте, как обеспечить соблюдение и мониторинг вызовов на защищенных сайтах с помощью Firebase Studio.

Что дальше?

  • Ознакомьтесь с документацией по проверке приложений для Google Maps Javascript API.
  • Узнайте больше о проверке приложений в Firebase.
  • Попробуйте еще одну лабораторную работу с App Check и API Google Maps Places.
  • Узнайте больше о reCAPTCHA .