Utiliser App Check pour sécuriser votre clé API Maps JavaScript

1. Avant de commencer

Page affichant l'application en fonctionnement

Objectifs de l'atelier

Dans cet atelier de programmation, vous allez utiliser App Check pour ajouter une couche de protection supplémentaire à votre clé API utilisée dans un environnement Web.

Plus précisément, les étapes suivantes seront suivies dans l'atelier de programmation pour relier les fonctionnalités :

  • Créez une page Web pour héberger une carte à l'aide de l'API Google Maps Platform JavaScript.
  • Hébergez la page pour qu'elle soit accessible en ligne.
  • Limitez les domaines et les API pouvant utiliser l'API à l'aide de la console Cloud.
  • Ajoutez et initialisez la bibliothèque App Check via Firebase.
  • Ajoutez le fournisseur d'attestation pour vérifier la validité des applications.
  • Appliquez la vérification sur votre application et surveillez-la.

À la fin de l'atelier de programmation, vous devriez disposer d'un site fonctionnel qui applique la sécurité aux clés API utilisées, aux domaines à partir desquels elles sont accessibles et aux types d'applications qui peuvent les utiliser.

2. Prérequis

L'activation d'App Check nécessite l'utilisation de trois services Google pour assurer la protection. Vous devez vous familiariser avec ces domaines.

Firebase : ce service permet de s'assurer que les clés API sont référencées à partir des domaines appropriés. Vous bénéficierez également des fonctionnalités d'hébergement et de déploiement grâce à Firebase Studio.

reCAPTCHA : fournit la fonctionnalité permettant de vérifier si des humains utilisent l'application et fournit également les clés publiques et privées pour connecter Firebase au domaine de l'application cliente.

Google Cloud Platform : fournit les clés API utilisées par Google Maps Platform et Firebase, ainsi que la restriction sur le domaine utilisant la clé Maps.

Le schéma d'architecture suivant montre comment tous ces éléments fonctionnent ensemble :

Présentation de l'architecture du système

Lorsque vous utilisez App Check et Google Maps Platform, les éléments suivants fonctionnent ensemble pour déterminer si les requêtes proviennent d'une application et d'un utilisateur valides, à l'aide de l'attestation fournie par un fournisseur d'attestation, en l'occurrence reCAPTCHA.

Pour ce faire, il utilise le SDK App Check fourni par Firebase, qui vérifie la validité de l'application appelante, puis fournit un jeton à l'application à l'aide duquel les appels ultérieurs à l'API JavaScript Google Maps Platform sont effectués. L'API Google Maps Platform JavaScript vérifie ensuite la validité du jeton fourni avec Firebase pour s'assurer qu'il provient à la fois du bon domaine et d'un utilisateur valide via le fournisseur d'attestation.

Pour en savoir plus sur l'utilisation d'App Check et de l'API Maps JavaScript, consultez la page suivante. Vous devez vous familiariser avec les étapes requises.

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

3. Configuration

Si vous n'avez pas encore de compte Google Cloud, vous devrez en configurer un avec la facturation activée au début. Suivez les instructions pour le créer avant de commencer.

Configurer Google Maps Platform

Si vous ne disposez pas encore d'un compte Google Cloud Platform et d'un projet pour lequel la facturation est activée, consultez le guide Premiers pas avec Google Maps Platform pour savoir comment créer un compte de facturation et un projet.

  1. Dans Cloud Console, cliquez sur le menu déroulant des projets, puis sélectionnez celui que vous souhaitez utiliser pour cet atelier de programmation.

  1. Activez les API et les SDK Google Maps Platform requis pour cet atelier de programmation dans Google Cloud Marketplace. Pour ce faire, suivez les étapes indiquées dans cette vidéo ou dans cette documentation.
  2. Générez une clé API sur la page Identifiants de Cloud Console. Vous pouvez suivre la procédure décrite dans cette vidéo ou dans cette documentation. Toutes les requêtes envoyées à Google Maps Platform nécessitent une clé API.

Autres conditions requises pour cet atelier de programmation

Pour suivre cet atelier de programmation, vous aurez besoin des comptes, des services et des outils suivants :

  • Connaissances de base sur JavaScript, HTML et CSS
  • Un compte Google Cloud pour lequel la facturation est activée (comme indiqué)
  • Une clé API Google Maps Platform pour laquelle l'API Maps JavaScript est activée (cette étape sera effectuée pendant l'atelier de programmation).
  • Vous avez des connaissances de base sur l'hébergement et le déploiement Web (vous serez guidé tout au long de l'atelier de programmation). Cela se fera via la console Firebase et Firebase Studio.
  • Un navigateur Web pour afficher les fichiers pendant que vous travaillez.

4. Créer une page dans Firebase Studio

Cet atelier de programmation ne suppose pas que vous ayez déjà créé une application. Il utilise Firebase Studio pour créer une page permettant d'héberger l'application Maps et de la déployer sur Firebase à des fins de test. Si vous disposez déjà d'une application, vous pouvez également l'utiliser en modifiant les domaines hôtes, les extraits de code et les clés API appropriés pour assurer une implémentation correcte.

Accédez à Firebase Studio (vous devez disposer d'un compte Google) et créez une application Simple HTML. Vous devrez peut-être cliquer sur le bouton "See all templates" (Afficher tous les modèles) pour afficher cette option ou simplement cliquer sur ce lien pour y accéder directement.

Image montrant le modèle HTML simple

Attribuez un nom approprié à l'espace de travail, par exemple myappcheck-map (plus un nombre aléatoire pour le rendre unique, qui sera ajouté automatiquement). Firebase Studio crée ensuite l'espace de travail.

Image montrant les nouvelles options Workspace

Une fois le nom saisi, vous pouvez cliquer sur le bouton "Créer" pour lancer le processus de création du projet.

Image montrant la boîte de dialogue de création de projet

Une fois le fichier créé, vous pouvez remplacer le texte du fichier index.html par le code suivant, qui crée une page avec une carte.

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

Lorsque vous l'exécutez, devrait afficher une page montrant une carte de l'application fonctionnelle, comme indiqué sur l'image, mais !

Image montrant l&#39;application en fonctionnement.

Toutefois, une erreur s'affichera lorsque la page sera réellement chargée, car elle aura besoin d'une clé API Google Maps Platform, qui sera ajoutée dans une section ultérieure.

Image montrant la notification &quot;Un problème est survenu&quot;.

Le message d'erreur réel peut être consulté dans la console Web de Firebase Studio.

Message d&#39;erreur indiquant que la clé n&#39;est pas valide.

Pour résoudre ce problème, nous devons ajouter une clé API à la page. La clé API permet d'associer la page et l'implémentation de l'API Maps JavaScript. Il s'agit également d'une zone d'exploitation, car elle doit être contenue dans la page de manière non chiffrée, où la clé API peut être récupérée et utilisée sur différents sites.

Une méthode de protection consiste à utiliser des restrictions liées aux applications, soit par le biais du type d'application utilisée, soit par le biais du domaine ou de l'adresse IP de provenance appelés. Pour en savoir plus sur les bonnes pratiques, consultez le site suivant :

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

ou par le biais d'appels directs depuis la ligne de commande ou le serveur, les applications qui n'ont elles-mêmes aucun moyen de fournir un referrer ou d'être suivies constituent potentiellement une faille de sécurité.

5. Créer une application Firebase

Firebase est utilisé pour fournir la fonctionnalité permettant d'associer le fournisseur d'attestation afin de vérifier les éléments suivants :

  • Les requêtes proviennent de votre application authentique
  • Les requêtes proviennent d'une session utilisateur et d'un appareil authentiques et non modifiés.

Dans cet atelier de programmation, reCAPTCHA v3 sera utilisé comme fournisseur de cette attestation.

Créez une application Firebase et hébergez-la.

Accédez à https://firebase.google.com/ et créez un projet Firebase à partir du lien Accéder à la console.

Image montrant le lien vers la console

Créez un projet en cliquant sur la zone suivante.

Créez un projet Firebase.

Choisissez un nom pour le projet, par exemple Mon projet App Check. Il n'est pas nécessaire qu'il soit identique à celui utilisé précédemment, car il ne sert que de référence. Le nom réel du projet peut être modifié juste en dessous du texte. Il sera composé du nom que vous avez saisi et, s'il n'est pas unique, un numéro y sera ajouté.

Image montrant comment saisir le nom du projet.

Si vous êtes invité à ajouter d'autres services (tels que Google Analytics) à votre application, vous pouvez les accepter ou non. Toutefois, ils ne sont pas nécessaires pour cet atelier de programmation et peuvent donc être ignorés.

Cliquez sur le bouton "Créer un projet" et attendez que le projet soit créé. Vous recevrez une notification une fois l'opération terminée.

Image montrant la boîte de dialogue de création d&#39;un projet.

Cliquez sur "Continuer" lorsque vous êtes prêt à interagir avec le projet.

Image montrant la boîte de dialogue &quot;Projet terminé&quot;.

Sur la page principale, vous pouvez choisir de commencer en ajoutant Firebase à votre application et en sélectionnant l'option Web.

Commencez par ajouter.

Choisissez de configurer Firebase Hosting pour votre site afin de déterminer où les fichiers seront placés une fois déployés (pour votre site, vous pouvez utiliser votre propre option, mais pour suivre cet atelier de programmation, vous allez déployer sur Firebase Hosting).

Enregistrez la nouvelle application.

Cliquez sur "Register app" (Enregistrer l'application) pour créer l'application. Vous allez ensuite prendre le script créé et l'utiliser pour référencer le projet dans Firebase à partir de notre application Web.

Le code de configuration Firebase de l'onglet suivant sera utilisé dans l'application pour connecter Firebase et les API Maps. Il est donc intéressant de le copier à partir de la section Utiliser la balise de script. que vous collerez dans le fichier index.html du projet.

Balise de script à inclure sur la page.

Cliquez sur "Suivant" pour les autres sections, puis consultez l'application créée dans la section des paramètres du projet du site.

Si vous avez besoin de revenir en arrière et de retrouver les détails de la configuration ultérieurement, vous pouvez également trouver les détails de l'application à partir du bouton "Paramètres", comme indiqué :

Élément de menu &quot;Paramètres du projet&quot;.

Avant de quitter cette section, vous devrez noter le domaine du site d'hébergement Firebase créé pour une utilisation ultérieure avec reCAPTCHA. Cela permet d'associer le nom du site au fournisseur d'attestation, ce qui signifie que seules les demandes provenant de ce site seront vérifiées.

Accédez à la section "Hébergement" depuis les raccourcis du projet ou le menu "Créer" sur la gauche.

Image montrant le raccourci d&#39;hébergement. ou Image montrant le menu de compilation de l&#39;hébergement.

Dans cette section, recherchez le domaine qui a été créé pour l'application. Si ce n'est pas déjà fait, vous devrez peut-être cliquer sur plusieurs écrans pour le configurer.

Image montrant la boîte de dialogue du domaine d&#39;hébergement.

6. Sécuriser les clés API

Accédez à la console Cloud avec le même compte que celui que vous utilisez pour Firebase afin de consulter le projet qui a été créé.

lien

Image montrant le lien Cloud Console

Si vous avez plusieurs projets, vous devrez peut-être utiliser le menu déroulant ou le champ de recherche pour sélectionner le bon projet, avec le nom de votre projet Firebase.

Image montrant la liste &quot;Sélectionner un projet&quot;

Le projet que vous venez de créer s'ouvre. Vous allez maintenant ajouter l'API Maps JavaScript à ce projet afin qu'elle puisse être utilisée dans le projet, y compris en limitant son utilisation à une clé API et à un domaine d'hébergement spécifiques.

Image montrant la page d&#39;accueil du projet.

Utilisez le menu de gauche pour activer les API Maps dans le projet. Sélectionnez l'option "API et services", puis "API et services activés".

Image montrant le menu &quot;Activer des API&quot; utilisé.

Sélectionnez l'option "ACTIVER LES API ET LES SERVICES".

Image montrant le menu &quot;Sélectionner et activer des API&quot;.

Saisissez "Maps JavaScript API" dans le champ de recherche.

Image montrant le champ de recherche de l&#39;API

Sélectionnez le résultat correspondant.

Image montrant la case &quot;Sélectionner l&#39;API correspondante&quot;

Cliquez ensuite sur "Activer" pour ajouter l'API à votre projet (cette étape peut déjà avoir été effectuée si vous avez déjà utilisé ce projet).

Image montrant la case &quot;Activer l&#39;API correspondante&quot;

Une fois cette option activée, vous pouvez choisir d'ajouter une clé API et de la restreindre, mais pour l'instant, nous allons passer cette étape.

À l'aide des options du menu de gauche, revenez à la section "API et services", puis sélectionnez la clé de navigateur qui a été créée pour vous.

Image montrant la restriction des API.

Ajoutez l'API Maps JavaScript à l'une des restrictions d'API.

Sélectionnez l&#39;API Maps pour le filtrage.

Pour les clés d'une application en ligne, vous devez également limiter le domaine qui héberge l'application. Faites-le maintenant en utilisant le domaine créé pour vous dans Firebase. Vous devez également ajouter /* à la fin du domaine pour vous assurer qu'il couvre tous les chemins d'accès.

Domaine auquel la restriction s&#39;applique.

Pour en savoir plus sur l'activation de cette fonctionnalité et la restriction des clés API, consultez la page suivante.

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

7. Créer des secrets reCAPTCHA

L'étape suivante consiste à créer un projet reCAPTCHA pour fournir l'attestation et les clés pour le client et le serveur.

Accédez au site reCAPTCHA à l'adresse https://www.google.com/recaptcha/, puis cliquez sur le bouton "Commencer".

Image montrant &quot;Premiers pas avec reCAPTCHA&quot;.

Ensuite, enregistrez un nouveau site et assurez-vous de saisir le bon domaine à restreindre.

Image montrant l&#39;enregistrement d&#39;un site reCAPTCHA.

Si vous en avez plusieurs, assurez-vous également d'avoir sélectionné le même projet Google Cloud que celui créé par Firebase.

Cela crée deux clés : une clé secrète que vous saisirez dans la console Firebase (elle ne doit jamais être placée sur une page ni dans une application qui peut être consultée publiquement) et une clé de site que vous utiliserez dans l'application Web.

Image de la page des clés reCAPTCHA.

Laissez cette page ouverte, car vous en aurez besoin. Cliquez sur le bouton "Copier la clé secrète", puis revenez sur le site Firebase.

8. Ajouter reCAPTCHA à Firebase

Dans la console d'administration Firebase, accédez aux éléments du menu de gauche. Sous l'élément de menu Build (Créer), sélectionnez App Check.

Image montrant le menu de compilation de l&#39;hébergement.

La liste des services ne peut pas être activée tant qu'aucune application n'est enregistrée (elle a été créée précédemment lorsque l'hébergement a été ajouté au site). Cliquez sur "Commencer" si vous devez la configurer.

Cliquez sur l'onglet "App" (Application), ouvrez l'application Web, saisissez le code secret que vous avez copié depuis le site reCAPTCHA, puis cliquez sur "Save" (Enregistrer).

Image montrant la saisie du code secret

Une coche verte doit maintenant s'afficher à côté du fournisseur reCAPTCHA. Cette application Web peut désormais utiliser reCAPTCHA pour attester qu'un utilisateur ou un site appelle correctement le service.

Coche verte indiquant que reCAPTCHA est activé

Dans l'onglet "API", l'API Google Maps Platform devrait maintenant être active, mais non appliquée.

App Check est actif, mais non appliqué.

Vous avez maintenant associé le secret reCAPTCHA au projet Firebase. Vous pouvez maintenant ajouter le code à la page Web pour faire correspondre la clé du site au bon fournisseur à utiliser avec l'application Maps.

reCAPTCHA vérifie que la clé de site correspond à la clé secrète. Une fois cette vérification effectuée, il confirme que la page appelante est correcte et App Check fournit un jeton qui peut être utilisé par les appels suivants à l'API Maps JavaScript. Sans cette attestation, le jeton ne sera pas fourni et les requêtes ne pourront pas être validées.

9. Ajoutez la validation à la page et déployez-la.

Revenez à la console Cloud et copiez la clé API à utiliser pour l'API Maps.

Vous trouverez cette option dans le menu latéral de la console, sous le menu latéral "API et services", puis sous l'option "Identifiants".

Image montrant le menu &quot;Identifiants&quot;.

Vous pouvez alors sélectionner la clé de navigateur existante (mais, comme indiqué, vous pouvez utiliser une autre clé existante ou en créer une).

Image montrant l&#39;option &quot;Clé de navigateur existante&quot;.

Cliquez sur le bouton "Afficher la clé", puis copiez la clé dans la boîte de dialogue qui s'affiche.

Revenez au projet Firebase Studio dans lequel la page HTML que vous avez créée a été ouverte précédemment. Vous pouvez maintenant ajouter la clé API à la page pour que l'API Maps fonctionne là où la page comporte "YOUR_API_KEY".

Mettre à jour la clé API

Si vous exécutez à nouveau la page, un message d'erreur différent s'affiche.

Message d&#39;erreur &quot;Référent non autorisé&quot;

Cela signifie que le domaine de développement à partir duquel vous hébergez la page n'est pas autorisé (nous n'avons ajouté que le domaine déployé). Nous devrons publier ce site sur le bon domaine à l'aide de Firebase Hosting. Pour en savoir plus, consultez :

Déployer avec Firebase Hosting

et cette vidéo

Créez, testez et déployez plus rapidement vos applications Web Firebase dans Project IDX

Erreur &quot;La facturation n&#39;est pas activée&quot;.

Pour en savoir plus, consultez Erreurs de chargement de la carte sur le site de l'API Maps JavaScript.

Si vous recevez l'erreur RefererNotAllowedMapError, vous pouvez la corriger en déployant la page sur le bon domaine.

Revenez à Firebase Studio et cliquez sur l'icône "Firebase Studio" (elle peut se trouver tout à gauche ou tout à droite, selon l'option que vous avez configurée) pour ouvrir les options d'hébergement.

Image montrant l&#39;icône Firebase Studio.

Dans cet atelier de programmation, vous devez ensuite "Héberger l'application avec Firebase" pour connecter votre instance Firebase à l'application Studio.

Option &quot;Héberger avec Firebase&quot;.

Cliquez ensuite sur Authentifier Firebase pour lancer le processus d'authentification. Votre compte pourra ainsi automatiser l'hébergement avec le backend depuis Studio.

Image montrant l&#39;option &quot;Authentifier Firebase&quot;.

Suivez les instructions de la fenêtre de commande pour autoriser le déploiement.

Image montrant les instructions d&#39;authentification.

Suivez les instructions à l'écran (y compris l'ouverture d'une nouvelle fenêtre), copiez le code d'autorisation à l'endroit où il est demandé, puis collez-le dans la fenêtre de commande de Firebase Studio.

Image montrant le code d&#39;autorisation Firebase.

Pour en savoir plus sur cette procédure, consultez :

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

Une fois cette opération effectuée, vous pouvez cliquer sur "initialize firebase hosting" (initialiser Firebase Hosting) pour associer le projet au projet Firebase.

Sélectionnez "Utiliser un projet existant", puis sélectionnez le projet que vous avez créé dans la section précédente. Acceptez les autres valeurs par défaut (votre exemple peut varier en fonction du nom que vous choisissez lors de la configuration du projet).

Configuration d&#39;un projet Firebase Hosting

Revenez à la vue de l'explorateur et remplacez le fichier index.html créé dans le répertoire public par celui que vous aviez déjà dans le répertoire racine.

Image montrant la structure des fichiers d&#39;hébergement.

Vous pouvez maintenant revenir à la barre latérale Firebase Studio et déployer le site en production.

Image montrant le déploiement en production.

Les étapes de déploiement s'affichent dans la console.

Image montrant les étapes de déploiement.

Ouvrez le site déployé à partir de l'URL d'hébergement affichée (ici, https://my-app-check-project.web.app/, mais elle sera différente pour votre projet).

L'application affiche désormais la carte sur la page, car les API fonctionnent pour les domaines utilisés.

Image montrant le menu de compilation de l&#39;hébergement.

Vous disposez désormais d'une page fonctionnelle, avec des contraintes appliquées au type d'API pouvant être utilisé avec la clé API, ainsi qu'aux domaines pour lesquels la clé API peut être utilisée. L'étape suivante consiste à restreindre l'accès à ce domaine uniquement. Pour ce faire, vous devrez ajouter la section de script Firebase générée précédemment afin de sécuriser la page à l'aide d'App Check. Nous le ferons dans la section suivante.

10. Page sécurisée

Bien que la page actuelle sécurise la clé API pour le domaine, elle n'ajoute pas l'étape d'attestation pour s'assurer qu'elle est utilisée par la bonne application et par une personne. La clé peut toujours être volée et utilisée par un acteur malveillant. Pour arrêter cette configuration Firebase, le fournisseur et la clé du site doivent être ajoutés à la page afin d'obtenir le jeton approprié pour le client.

Vous pouvez également constater que l'utilisation de l'API Maps est suivie dans Firebase. Comme il n'utilise aucun jeton valide, il envoie des requêtes non validées.

Vous pouvez obtenir les informations de connexion requises à partir du projet Firebase.

Récupérez les informations Firebase dans la console contenant les détails de configuration Firebase. Accédez à la page des paramètres du projet sous Firebase, puis, dans la section CDN de l'application, récupérez la section de code pour la configuration du CDN (la plus simple).

Dans le projet Firebase, cliquez sur l'icône en forme de roue dentée pour afficher les paramètres du projet.

Image montrant les paramètres d&#39;un projet Firebase

La page suivante s'ouvre et contient les informations de la section "Général", sous "Vos applications".

Paramètres de configuration de l&#39;application Firebase.

Copiez-le dans la page Firebase Studio (public/index.html) qui contient la carte et qui est hébergée. Il se présentera comme suit (avec vos informations et non celles de ce fichier) :

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

Maintenant que Firebase a été ajouté à notre application, les appels à la bibliothèque reCAPTCHA à l'aide de la clé de site fournie que vous avez obtenue précédemment sur le site reCAPTCHA (avant).

Image montrant la saisie d&#39;une clé de site reCAPTCHA.

Pour en savoir plus sur l'ajout de ces sections, consultez la page de documentation Maps suivante :

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

Ajoutez la bibliothèque App Check à la page, puis chargez les fonctions pour initialiser App Check avec la configuration Firebase et obtenir le jeton à l'aide de ReCaptchaV3Provider.

Commencez par importer la bibliothèque App Check :

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

Ensuite, ajoutez le code pour initialiser App Check avec la configuration Firebase et le fournisseur reCAPTCHA à l'aide du jeton de site.

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

Enfin, associez une fonction au contrôle de la carte à l'aide de la fonction de paramètres de la bibliothèque Maps Core pour obtenir un jeton. Les demandes de jetons seront effectuées selon les besoins du contrôle de la carte, en fonction de la durée de vie des jetons.

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

Voici le fichier complet :

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

Déployez-le sur le site Firebase à l'aide de Firebase Studio et exécutez la page.

11. Appliquer la surveillance

Maintenant que la page est configurée, vous pouvez voir qu'elle est vérifiée lorsqu'elle est exécutée. Revenez à la console Firebase et rouvrez la section "App Check". App Check devrait maintenant surveiller l'API Maps JavaScript.

Vérification de l&#39;activation de la surveillance.

Si vous ouvrez la fenêtre, vous verrez que les clients envoient des requêtes et que l'attestation fonctionne (les requêtes validées en bleu foncé s'affichent sur le graphique). D'autres demandes afficheront des appels pendant la phase de développement avant la fin de la validation.

Graphique montrant les demandes validées.

Maintenant que les clients fonctionnent, vous pouvez activer l'application des règles sur le site pour vous assurer que les clés API ne peuvent pas être utilisées à partir d'une application cliente non valide. Cliquez sur le bouton "Appliquer" pour lancer l'application.

Image montrant le bouton d&#39;application.

En cliquant sur ce bouton, vous verrez un grand panneau d'avertissement indiquant que votre application sera verrouillée. Dans la réalité, vous ne devez le faire que lorsque vous savez que tous vos clients disposent des bonnes clés et fonctionnent correctement. Sinon, vos utilisateurs risquent de ne pas pouvoir accéder au site.

Image montrant la boîte de dialogue d&#39;application.

La mise en application peut également prendre un certain temps. Si vous testez l'application des règles immédiatement, il est possible que les modifications n'aient pas eu le temps de se propager (ce qui est indiqué à l'écran).

15 minutes pour l&#39;appliquer.

Lorsque vous demandez la page, vous devriez la voir fonctionner comme avant. En effet, rien n'a changé sur le site.

Au fil du temps, le nombre de demandes validées dans la console devrait augmenter, comme illustré ci-dessous :

Graphique montrant une augmentation des demandes de validation.

Pour vérifier que cela fonctionne, revenez à l'exemple d'origine de l'atelier de programmation et créez une page sans la fonctionnalité App Check. Nommez cette page, par exemple, "nocheck.html" et placez-la dans le dossier public, au même emplacement qu'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>

Une fois que vous avez effectué cette opération et saisi la clé API correcte, lorsque vous demandez la page (utilisez votredomaine/nocheck.html), la zone d'erreur grise suivante devrait s'afficher.

Erreur &quot;Un problème est survenu&quot;

En consultant la console, vous devriez voir un message d'erreur semblable à celui-ci :

Message d&#39;erreur &quot;App Check non valide&quot;

App Check a bien bloqué la demande de carte sur la page, car il ne reçoit plus le jeton App Check pour le site appliqué.

12. Félicitations !

Félicitations, vous avez bien activé App Check sur votre site !

Page affichant l&#39;application en fonctionnement

Vous avez créé une application qui utilise Firebase App Check pour s'assurer que les requêtes proviennent d'un domaine et d'un utilisateur valides.

Ce que vous avez appris

  • Découvrez comment utiliser Firebase Studio pour héberger et déployer une page Web.
  • Découvrez comment utiliser la console Cloud pour activer et sécuriser les API Google Maps Platform.
  • Découvrez comment utiliser reCAPTCHA pour générer des clés pouvant être utilisées pour attester des appels.
  • Découvrez comment utiliser Firebase App Check et l'intégrer à l'API Maps JavaScript.
  • Découvrez comment appliquer et surveiller les appels vers des sites protégés avec Firebase Studio.

Étape suivante

  • Consultez la documentation pour App Check pour l'API Google Maps JavaScript.
  • En savoir plus sur App Check dans Firebase
  • Essayez un autre atelier de programmation avec App Check et l'API Google Maps Places.
  • En savoir plus sur reCAPTCHA