שימוש ב-App Check כדי לאבטח את מפתח Maps JavaScript API

1. לפני שמתחילים

דף שבו מוצגת האפליקציה הפועלת

מה תפַתחו.

ב-codelab הזה תשתמשו ב-App Check כדי להוסיף עוד שכבת הגנה למפתח ה-API שבו אתם משתמשים בסביבת אינטרנט.

במהלך ה-Codelab, תפעלו לפי השלבים הבאים כדי לקשר בין הפונקציות:

  • יוצרים דף אינטרנט לאירוח מפה באמצעות Google Maps Platform Javascript API.
  • מארחים את הדף כך שאפשר יהיה לגשת אליו באינטרנט.
  • אפשר להגביל את הדומיינים וממשקי ה-API שיכולים להשתמש במפתח ה-API באמצעות מסוף Cloud.
  • מוסיפים ומפעילים את ספריית App Check דרך Firebase.
  • מוסיפים את ספק האימות כדי לבדוק את תוקף האפליקציות.
  • אפשר לאכוף את הבדיקה באפליקציה ולעקוב אחרי התוצאות.

בסוף ה-codelab אמור להיות לכם אתר פעיל שמחיל אכיפה של אבטחה על מפתחות ה-API שבשימוש, על הדומיינים שמהם יש גישה למפתחות ועל סוגי האפליקציות שיכולות להשתמש בהם.

2. דרישות מוקדמות

כדי להפעיל את App Check, צריך להשתמש בשלושה שירותים של Google כדי לספק את ההגנה. כדאי להכיר את התחומים האלה.

Firebase – השירות הזה אוכף את השימוש במפתחות ה-API רק בדומיינים המתאימים. השילוב הזה יאפשר גם להשתמש בפונקציות של אירוח ופריסה באמצעות Firebase Studio.

reCAPTCHA – מספק את הפונקציונליות לבדיקה אם בני אדם משתמשים באפליקציה, וגם מספק את המפתחות הציבוריים והפרטיים לקישור Firebase לדומיין של אפליקציית הלקוח.

Google Cloud Platform – כאן מופיעים מפתחות ה-API שמשמשים את הפלטפורמה של מפות Google ואת Firebase, וההגבלה על הדומיין שמשתמש במפתח של מפות Google.

בתרשים הארכיטקטורה הבא אפשר לראות איך כל הרכיבים האלה פועלים יחד:

סקירה כללית של ארכיטקטורת המערכת

כשמשתמשים ב-App Check וב-Google Maps Platform, הרכיבים הבאים פועלים יחד כדי לקבוע אם הבקשות מגיעות מאפליקציה וממשתמש תקפים, באמצעות אישור שסופק על ידי ספק אישורים, במקרה הזה reCAPTCHA.

הבדיקה מתבצעת באמצעות App Check SDK שסופק על ידי Firebase. ה-SDK בודק את התוקף של האפליקציה שמבצעת את הקריאה, ואז מספק לאפליקציה אסימון שבאמצעותו מתבצעות קריאות עתידיות ל-Google Maps Platform JavaScript API. בתמורה, ממשק ה-API של Javascript בפלטפורמה של מפות Google בודק את התוקף של הטוקן שסופק באמצעות Firebase כדי לוודא שהוא מגיע מהדומיין הנכון וגם מספק האימות ממשתמש תקף.

פרטים נוספים על השימוש ב-App Check ובממשק API של JavaScript במפות Google זמינים במיקום הבא. מומלץ לעיין בשלבים הנדרשים.

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

3. להגדרה

אם עדיין אין לכם חשבון Google Cloud, תצטרכו להגדיר אחד עם חיוב מופעל בהתחלה. לפני שמתחילים, פועלים לפי ההוראות כדי ליצור את המרכז.

הגדרת הפלטפורמה של מפות Google

אם עדיין אין לכם חשבון ב-Google Cloud Platform ופרויקט עם חיוב מופעל, תוכלו לעיין במדריך תחילת העבודה עם הפלטפורמה של מפות Google כדי ליצור חשבון לחיוב ופרויקט.

  1. בCloud Console, לוחצים על התפריט הנפתח של הפרויקט ובוחרים את הפרויקט שבו רוצים להשתמש ב-codelab הזה.

  1. מפעילים את ממשקי ה-API וערכות ה-SDK של הפלטפורמה של מפות Google שנדרשים ל-codelab הזה ב-Google Cloud Marketplace. כדי לעשות זאת, פועלים לפי השלבים בסרטון הזה או בתיעוד הזה.
  2. יוצרים מפתח API בדף Credentials במסוף Cloud. אפשר לפעול לפי השלבים שמפורטים בסרטון הזה או בתיעוד הזה. כל הבקשות אל הפלטפורמה של מפות Google דורשות מפתח API.

דרישות נוספות ל-Codelab הזה

כדי להשלים את ה-codelab הזה, תצטרכו את החשבונות, השירותים והכלים הבאים:

  • ידע בסיסי ב-JavaScript, ב-HTML וב-CSS
  • חשבון Google Cloud עם חיוב מופעל (כמו שצוין)
  • מפתח API של הפלטפורמה של מפות Google עם Maps JavaScript API מופעל (הפעולה הזו תתבצע במהלך ה-codelab).
  • הבנה בסיסית של אירוח ופריסה של אתרים (ההסבר על זה יופיע ב-codelab). הפעולה הזו תתבצע דרך מסוף Firebase ו-Firebase Studio.
  • דפדפן אינטרנט לצפייה בקבצים בזמן העבודה.

4. יצירת דף ב-Firebase Studio

ב-codelab הזה לא מניחים שכבר יצרתם אפליקציה, ומשתמשים ב-Firebase Studio כדי ליצור דף לאירוח אפליקציית המפה ולפרוס אותה ב-Firebase למטרות בדיקה. אם יש לכם אפליקציה קיימת, אתם יכולים להשתמש בה במקום זאת, ולשנות את דומייני המארח המתאימים, קטעי הקוד ומפתחות ה-API כדי לוודא שההטמעה נכונה.

עוברים אל Firebase Studio (נדרש חשבון Google) ויוצרים אפליקציית Simple HTML חדשה. יכול להיות שתצטרכו ללחוץ על הלחצן See all templates (הצגת כל התבניות) כדי שהאפשרות הזו תופיע, או פשוט ללחוץ על הקישור הזה כדי לגשת ישירות.

תמונה שמציגה תבנית HTML פשוטה

נותנים לסביבת העבודה שם מתאים, כמו myappcheck-map (בתוספת מספר אקראי כדי שהשם יהיה ייחודי, המערכת תוסיף אותו בשבילכם). לאחר מכן, Firebase Studio ייצור את סביבת העבודה.

תמונה שמציגה אפשרויות חדשות ב-Workspace

אחרי שמזינים את השם, אפשר ללחוץ על לחצן היצירה כדי להתחיל את תהליך יצירת הפרויקט.

תמונה שמציגה את תיבת הדו-שיח ליצירת פרויקט

אחרי שיוצרים את הקובץ, אפשר להחליף את הטקסט בקובץ 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 Maps Platform. נסביר איך לעשות את זה בקטע הבא.

תמונה שבה מוצגת ההתראה &#39;משהו השתבש&#39;.

הודעת השגיאה בפועל עשויה להופיע במסוף האינטרנט ב-Firebase Studio.

הודעת שגיאה לגבי מפתח לא תקין.

כדי לפתור את הבעיה, צריך להוסיף מפתח API לדף. מפתח ה-API הוא הדרך שבה הדף וההטמעה של Maps JavaScript API קשורים זה לזה. זה גם אזור שניתן לניצול, כי המפתח צריך להיות בדף בצורה לא מוצפנת, כך שאפשר לקחת את מפתח ה-API ולהשתמש בו באתרים שונים.

אחת משיטות ההגנה היא באמצעות הגבלות על אפליקציות, לפי סוג האפליקציה שבה נעשה שימוש או לפי כתובת ה-IP או הדומיין המפנה שמתבצעת אליהם קריאה. מידע נוסף על שיטות מומלצות זמין באתר הבא:

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

או באמצעות שימוש בקריאות ישירות משורת הפקודה או מהשרת, אפליקציות שאין להן דרך לספק מפנה או להיות במעקב, ולכן הן עלולות להיות פרצת אבטחה.

5. יצירת אפליקציית Firebase

מערכת Firebase משמשת לקישור ספק האימות כדי לבדוק את הדברים הבאים:

  • הבקשות מגיעות מהאפליקציה המאומתת שלכם
  • הבקשות מגיעות ממכשיר ומסשן משתמש אותנטיים שלא בוצעו בהם שינויים.

ב-codelab הזה, reCAPTCHA v3 ישמש כספק של האימות הזה.

יצירת אפליקציה ואירוח ב-Firebase.

עוברים אל https://firebase.google.com/ ויוצרים פרויקט חדש ב-Firebase באמצעות הקישור Go to console (מעבר למסוף).

תמונה שמוצג בה קישור למסוף

כדי ליצור פרויקט חדש, לוחצים על האזור הבא.

יוצרים פרויקט חדש ב-Firebase.

בוחרים שם לפרויקט, למשל My App Check Project. השם לא חייב להיות זהה לשם שבו השתמשתם קודם, כי הוא רק לצורך הפניה. אפשר לערוך את השם בפועל של הפרויקט ממש מתחת לטקסט. השם יורכב מהשם שהזנתם, ואם הוא לא ייחודי, יתווסף לו מספר.

תמונה שבה מוצגים פרטים להזנת שם הפרויקט.

אם תתבקשו להוסיף שירותים אחרים (כמו Google Analytics) לאפליקציה, תוכלו לאשר או לדחות את הבקשה, אבל בשביל ה-codelab הזה הם לא נחוצים, ולכן אפשר לא להוסיף אותם.

לוחצים על הלחצן 'יצירת פרויקט' ומחכים עד שהפרויקט נוצר. תקבלו הודעה כשהתהליך יסתיים.

תמונה שמציגה את תיבת הדו-שיח ליצירת פרויקט.

לוחצים על 'המשך' כשמוכנים להתחיל אינטראקציה עם הפרויקט.

תמונה שבה מוצגת תיבת דו-שיח של פרויקט שהושלם.

בדף הראשי אפשר להתחיל בהוספת Firebase לאפליקציה ובחירה באפשרות 'אינטרנט'.

כדי להתחיל, מוסיפים.

בוחרים להגדיר את Firebase Hosting באתר כדי שיהיה מקום להעביר אליו את הקבצים אחרי הפריסה (באתר שלכם אתם יכולים להשתמש באפשרות משלכם, אבל כדי לבצע את השלבים במעבדת הקוד הזו תצטרכו לפרוס ל-Firebase Hosting).

רושמים את האפליקציה החדשה.

לוחצים על Register app (רישום אפליקציה) כדי ליצור את האפליקציה. בשלב הבא, לוקחים את הסקריפט שנוצר ומשתמשים בו כדי להפנות לפרויקט ב-Firebase מאפליקציית האינטרנט.

קוד ההגדרה של Firebase בכרטיסייה הבאה ישמש באפליקציה לקישור בין Firebase לבין ממשקי ה-API של מפות Google, ולכן כדאי להעתיק אותו מהקטע Use the script tag (שימוש בתג הסקריפט). מדביקים את הקוד בקובץ index.html של הפרויקט.

תג Script שצריך לכלול בדף.

לוחצים על 'הבא' כדי לעבור לקטעים האחרים, ואז רואים את האפליקציה שנוצרה בקטע 'הגדרות הפרויקט' באתר.

אם תצטרכו לחזור ולמצוא את פרטי ההגדרה במועד מאוחר יותר, תוכלו גם למצוא את פרטי האפליקציה באמצעות הלחצן 'הגדרות', כמו שמוצג כאן:

האפשרות Project settings (הגדרות הפרויקט) בתפריט.

לפני שיוצאים מהקטע הזה, צריך לרשום את הדומיין של אתר האירוח ב-Firebase שנוצר לשימוש מאוחר יותר עם reCAPTCHA. כך אפשר לקשר את שם האתר לספק האימות, כלומר רק בקשות מהאתר הזה יאומתו.

עוברים לקטע 'אירוח' מקיצורי הדרך של הפרויקט או מתפריט 'יצירה' בצד ימין.

תמונה שבה מוצג קיצור הדרך לאירוח. או תמונה שבה מוצג תפריט של בניית אירוח.

בקטע הזה מחפשים את הדומיין שנוצר עבור האפליקציה. אם עדיין לא הגדרתם את האפשרות הזו, יכול להיות שתצטרכו ללחוץ על כמה מסכים כדי להגדיר אותה.

תמונה שבה מוצגת תיבת דו-שיח של דומיין אירוח.

6. אבטחה של מפתחות API

נכנסים ל-Cloud Console באותו חשבון שבו משתמשים ב-Firebase כדי לראות את הפרויקט שנוצר,

link

תמונה שמוצג בה קישור ל-Cloud Console

אם יש לכם כמה פרויקטים, יכול להיות שתצטרכו להשתמש בתפריט הנפתח או בתיבת החיפוש כדי לבחור את הפרויקט הנכון, עם השם של פרויקט Firebase.

תמונה שבה מוצגת רשימת הפרויקטים לבחירה

הפרויקט החדש ייפתח. עכשיו תוסיפו את Maps JavaScript API לפרויקט הזה כדי שאפשר יהיה להשתמש בו בפרויקט, כולל הגבלת השימוש בו למפתח API ולדומיין אירוח ספציפיים.

תמונה שמציגה את דף הפתיחה של הפרויקט.

משתמשים בתפריט בצד ימין כדי להפעיל את ממשקי Maps APIs בפרויקט. בוחרים באפשרות 'APIs & Services' (ממשקי API ושירותים) ואז באפשרות 'Enabled APIs & Services' (ממשקי API ושירותים שמופעלים).

תמונה שבה רואים את התפריט &#39;הפעלת ממשקי API&#39; בשימוש.

בוחרים באפשרות ENABLE APIS AND SERVICES (הפעלת ממשקי API ושירותים).

תמונה שבה רואים את התפריט &#39;בחירת ממשקי API להפעלה&#39;.

מזינים 'Maps Javascript API' בתיבת החיפוש.

תמונה שבה רואים את תיבת החיפוש של ה-API

בוחרים את התוצאה התואמת.

תמונה שבה רואים את התיבה Select matched API (בחירת API תואם)

אחר כך לוחצים על 'הפעלה' בממשק ה-API כדי להוסיף אותו לפרויקט (יכול להיות שהפעולה הזו כבר בוצעה אם השתמשתם בפרויקט הזה בעבר).

תמונה שבה רואים את התיבה Enable matched API (הפעלת API תואם)

אחרי שמפעילים את האפשרות הזו, אפשר להוסיף מפתח API ולהגביל אותו, אבל בשלב הזה נדלג על זה.

באמצעות האפשרויות בתפריט הימני, חוזרים לקטע API & Services (ממשקי 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/ ולוחצים על הלחצן 'תחילת העבודה'.

תמונה שבה מוצג השלב &#39;תחילת העבודה עם reCAPTCHA&#39;.

לאחר מכן רושמים אתר חדש, ומוודאים שמזינים את הדומיין הנכון להגבלה.

תמונה שמראה רישום של אתר reCAPTCHA.

אם יש לכם יותר מפרויקט אחד, חשוב לוודא שבחרתם באותו פרויקט ב-Google Cloud שנוצר ב-Firebase.

הפעולה הזו יוצרת שני מפתחות: מפתח סודי שצריך להזין במסוף Firebase (אסור להזין אותו בדף או באפליקציה שגלויים לציבור), ומפתח אתר שמשמש באפליקציית האינטרנט.

תמונה שבה רואים את הדף &#39;מפתחות reCAPTCHA&#39;.

חשוב להשאיר את הדף הזה פתוח. לוחצים על הלחצן להעתקת המפתח הסודי וחוזרים לאתר Firebase.

8. הוספת reCAPTCHA ל-Firebase

במסוף Firebase Admin, עוברים לפריטי התפריט בצד ימין. בתפריט Build (בנייה), בוחרים באפשרות App Check.

תמונה שרואים בה את תפריט ההגדרות של אירוח.

אי אפשר להפעיל את רשימת השירותים עד שרושמים אפליקציה (האפליקציה נוצרה קודם כשנוספה אירוח לאתר). אם צריך להגדיר את זה, לוחצים על 'תחילת העבודה'.

לוחצים על הכרטיסייה 'אפליקציה', פותחים את אפליקציית האינטרנט, מזינים את הסוד שהעתקתם מאתר reCAPTCHA ולוחצים על 'שמירה'.

תמונה שבה רואים את הזנת הסוד

עכשיו אמור להופיע סימן וי ירוק לצד ספק ה-reCAPTCHA. עכשיו אפשר להשתמש באפליקציית האינטרנט הזו כדי לקבוע אם משתמש או אתר קוראים לשירות בצורה נכונה.

סימן וי ירוק שמופיע כש-reCAPTCHA מופעל

בכרטיסייה APIs (ממשקי API) אמורה להופיע עכשיו ההודעה שהפלטפורמה של מפות Google פעילה אבל לא נאכפת.

התכונה &#39;בדיקת אפליקציות&#39; פעילה אבל לא נאכפת.

קישרתם את הסוד של reCAPTCHA לפרויקט Firebase, ועכשיו אתם יכולים להוסיף את הקוד לדף האינטרנט כדי להתאים את מפתח האתר לספק הנכון לשימוש באפליקציית מפות Google.

מערכת reCAPTCHA בודקת שמפתח האתר תואם למפתח הסודי. אם יש התאמה, המערכת מאשרת שהדף שממנו מתבצעת הקריאה תקין, ושירות App Check מספק טוקן שאפשר להשתמש בו בקריאות הבאות אל Maps JavaScript API. בלי האישור הזה, הטוקן לא יינתן והבקשות לא יוכלו לעבור אימות.

9. מוסיפים אימות לדף ומבצעים פריסה.

חוזרים אל מסוף Cloud ומעתיקים את מפתח ה-API שצריך להשתמש בו עבור Maps API.

אפשר למצוא את האפשרות הזו בתפריט הצד במסוף, בתפריט הצד APIs and Services, באפשרות Credentials.

תמונה שבה מוצג תפריט פרטי הכניסה.

מכאן אפשר לבחור את מפתח הדפדפן הקיים (אבל כמו שצוין, אפשר להשתמש במפתח קיים אחר או ליצור מפתח חדש).

תמונה שבה מוצגת האפשרות &#39;מפתח דפדפן קיים&#39;.

לוחצים על לחצן הצגת המפתח ומעתיקים את המפתח מחלון הדו-שיח שמוצג.

חוזרים לפרויקט Firebase Studio שבו נפתח קודם דף ה-HTML שיצרתם. עכשיו אפשר להוסיף את מפתח ה-API לדף כדי שממשק Maps API יפעל במקום שבו מופיע "YOUR_API_KEY" בדף.

עדכון מפתח ה-API

אחרי שתפעילו מחדש את הדף, תוצג הודעת שגיאה אחרת.

הודעת השגיאה &#39;הפניה לא מורשית&#39;

המשמעות היא שהדומיין של הפיתוח שממנו מתארח הדף לא מורשה (הוספנו רק את הדומיין שבו הפריסה בוצעה). נצטרך לפרסם את האתר הזה בדומיין הנכון באמצעות אירוח ב-Firebase. פרטים נוספים זמינים בכתובת הבאה:

פריסה באמצעות אירוח ב-Firebase

ובסרטון הזה

פיתוח, בדיקה ופריסה מהירים יותר של אפליקציות אינטרנט ל-Firebase ב-Project IDX

שגיאה: החיוב לא מופעל.

פרטים נוספים זמינים בקטע Map Loading Errors באתר Maps JavaScript API.

אם מופיעה השגיאה RefererNotAllowedMapError, אפשר לפתור אותה על ידי פריסת הדף בדומיין הנכון.

חוזרים אל Firebase Studio ולוחצים על הסמל של Firebase Studio (יכול להיות שהוא יופיע בקצה הימני או השמאלי, בהתאם לאפשרות שהגדרתם) כדי לפתוח את אפשרויות האירוח.

תמונה שבה מוצג הסמל של Firebase Studio.

ב-codelab הזה, השלב הבא הוא 'אירוח האפליקציה באמצעות Firebase' כדי לקשר את מופע Firebase לאפליקציית Studio.

אפשרות לאירוח ב-Firebase.

אחר כך לוחצים על Authenticate Firebase (אימות Firebase) כדי להתחיל את תהליך האימות. כך תוכלו להפוך את האירוח לאוטומטי בחשבון שלכם באמצעות ה-Backend מתוך Studio.

תמונה שמוצגת בה האפשרות Authenticate Firebase (אימות Firebase).

פועלים לפי ההוראות בחלון הפקודות כדי לאשר את הפריסה.

תמונה שמציגה הוראות לאימות.

פועלים לפי ההוראות במסך (כולל פתיחת חלון חדש), מעתיקים את קוד ההרשאה במקום שבו מתבקשים לעשות זאת ומדביקים אותו בחלון הפקודות ב-Firebase studio.

תמונה שמוצג בה קוד הרשאה של Firebase.

פרטים נוספים על התהליך הזה זמינים בכתובת הבאה:

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

אחרי שמבצעים את הפעולה הזו, אפשר ללחוץ על initialize firebase hosting (הפעלת אירוח ב-Firebase) כדי לקשר את הפרויקט לפרויקט Firebase.

בוחרים באפשרות 'שימוש בפרויקט קיים' ובוחרים את הפרויקט שיצרתם בקטע הקודם. מאשרים את שאר ברירות המחדל (הדוגמה עשויה להשתנות בהתאם לשם שבוחרים כשמגדירים את הפרויקט).

הגדרת פרויקט Firebase hosting.

חוזרים לתצוגת הסייר ומחליפים את הקובץ index.html שנוצר בספרייה הציבורית בקובץ שכבר היה בספריית הבסיס.

תמונה שמציגה את מבנה קובץ האירוח.

עכשיו אפשר לחזור לסרגל הצד של Firebase Studio ולפרוס את האתר לסביבת ייצור.

תמונה שמציגה פריסה בסביבת ייצור.

שלבי הפריסה יוצגו במסוף.

תמונה שמציגה את שלבי הפריסה.

פותחים את האתר שנפרס מכתובת ה-URL של האירוח שמוצגת (בדוגמה כאן: https://my-app-check-project.web.app/, אבל היא תהיה שונה בפרויקט שלכם).

האפליקציה תציג עכשיו את המפה בדף, כי ממשקי ה-API פועלים בדומיינים שבהם נעשה שימוש.

תמונה שרואים בה את תפריט ההגדרות של אירוח.

עכשיו יש דף פעיל, עם אילוצים לגבי סוגי ממשקי ה-API שאפשר להשתמש בהם עם מפתח ה-API, וגם לגבי הדומיינים שאפשר להשתמש בהם במפתח ה-API. השלב הבא הוא להגביל את הגישה רק לדומיין הזה. כדי לעשות את זה, צריך להוסיף את קטע הסקריפט של Firebase שנוצר קודם כדי לאבטח את הדף באמצעות App Check. הסבר על כך מופיע בקטע הבא.

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.

פרטים נוספים על הוספת הקטעים האלה זמינים בדף התיעוד הבא של מפות Google:

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

מוסיפים את ספריית 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,
       });

לבסוף, מצמידים פונקציה ל-Map Control באמצעות פונקציית ההגדרות של ספריית 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 ופותחים שוב את הקטע App Check. מעכשיו, App Check ינטר את Maps Javascript API.

בודקים שהמעקב מופעל.

כשפותחים את החלון, אפשר לראות שהלקוחות שולחים בקשות ושהאימות פועל (הבקשות מוצגות בתרשים בצבע כחול כהה עם הכיתוב 'מאומת'). בבקשות אחרות יוצגו שיחות במהלך שלב הפיתוח, לפני שהאימות הושלם.

תרשים שמציג בקשות מאומתות.

עכשיו, אחרי שרואים שהלקוחות פועלים, אפשר להפעיל את האכיפה באתר כדי לוודא שלא ניתן להשתמש במפתחות ה-API מאפליקציית לקוח לא תקינה. לוחצים על הלחצן 'אכיפה' כדי להתחיל באכיפה.

תמונה שבה מוצג לחצן האכיפה.

אם תלחצו על האפשרות הזו, תוצג לכם אזהרה גדולה שלפיה האפליקציה תינעל. בעולם האמיתי, כדאי לעשות את זה רק כשאתם יודעים שלכל הלקוחות שלכם יש את המפתחות הנכונים והם פועלים. אחרת, יכול להיות שהמשתמשים לא יוכלו לגשת לאתר.

תמונה שבה מוצגת תיבת דו-שיח לאכיפה.

יכול להיות שייקח קצת זמן עד שהאכיפה תתבצע. אם תבדקו את האכיפה מיד, יכול להיות שהשינוי לא יספיק להתעדכן, כפי שמצוין במסך.

תוך 15 דקות.

כששולחים בקשה לדף, אמורה להיות לך אפשרות לראות שהוא פועל כמו קודם, כי לא בוצעו שינויים באתר.

עם הזמן, מספר הבקשות המאומתות במסוף אמור לעלות, כמו שרואים כאן:

תרשים שבו מוצגת עלייה במספר בקשות האימות.

כדי לבדוק שהיא פועלת, אפשר לחזור לדוגמה המקורית ב-codelab וליצור דף חדש בלי הפונקציונליות של בדיקת האפליקציה. נותנים לדף הזה שם כמו 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) אמורה להופיע תיבת השגיאה האפורה הבאה.

שגיאה: משהו השתבש.

במסוף אמורה להופיע הודעת שגיאה כמו זו:

הודעת שגיאה לא תקינה של App Check

הבדיקה של האפליקציה חסמה בהצלחה את הבקשה למפה בדף, כי האתר לא מקבל יותר את הטוקן של הבדיקה של האפליקציה.

12. מעולה!

הפעלת את App Check באתר שלך בהצלחה.

דף שבו מוצגת האפליקציה הפועלת

פיתחתם אפליקציה שמשתמשת ב-Firebase App Check כדי לוודא שהבקשות מגיעות מדומיין וממשתמש תקינים.

מה למדתם

  • איך משתמשים ב-Firebase Studio כדי לארח ולפרוס דף אינטרנט.
  • איך משתמשים במסוף Cloud כדי להפעיל ולאבטח ממשקי API של הפלטפורמה של מפות Google.
  • איך משתמשים ב-reCAPTURE כדי ליצור מפתחות שאפשר להשתמש בהם לאימות שיחות.
  • איך משתמשים ב-Firebase App Check ומשלבים אותו בממשק API של JavaScript במפות Google.
  • במאמר הזה מוסבר איך לאכוף ולנטר שיחות לאתרים מוגנים באמצעות Firebase Studio.

מה השלב הבא?