استخدام App Check لتأمين مفتاح Maps JavaScript API

1. قبل البدء

صفحة تعرض التطبيق الذي يتم العمل عليه

ما سيتم إنشاؤه

في هذا الدرس التطبيقي، ستستخدم خدمة App Check لإضافة طبقة حماية أخرى إلى مفتاح واجهة برمجة التطبيقات المستخدَم في بيئة الويب.

على وجه التحديد، سيتم اتّباع الخطوات التالية من خلال Codelab لربط الوظائف ببعضها:

  • أنشئ صفحة ويب لاستضافة خريطة باستخدام Google Maps Platform Javascript API.
  • استضافة الصفحة حتى يمكن الوصول إليها على الإنترنت
  • يمكنك حصر النطاقات وواجهات برمجة التطبيقات التي يمكنها استخدام واجهة برمجة التطبيقات من خلال Cloud Console.
  • أضِف مكتبة App Check وأعِد ضبطها من خلال Firebase.
  • أضِف مقدّم خدمة الإقرار للتأكّد من صحة التطبيقات.
  • فرض التحقّق من تطبيقك ومراقبته

في نهاية هذا الدرس العملي، يجب أن يكون لديك موقع إلكتروني يعمل على فرض الأمان على كلّ من مفاتيح واجهة برمجة التطبيقات المستخدَمة والنطاقات التي يتم الوصول إليها منها وأنواع التطبيقات التي يمكنها استخدامها.

2. المتطلبات الأساسية

يتطلّب تفعيل App Check استخدام ثلاث خدمات من Google لتوفير الحماية، لذا عليك التعرّف على هذه المجالات.

Firebase: توفّر هذه الخدمة فرض استخدام الخدمات التي تتحقّق من أنّ مفاتيح واجهات برمجة التطبيقات تتم الإشارة إليها من النطاقات المناسبة. سيتيح ذلك أيضًا وظائف الاستضافة والنشر من خلال استخدام Firebase Studio.

reCAPTCHA: توفّر هذه الخدمة وظيفة التحقّق من أنّ المستخدمين هم أشخاص حقيقيون، كما توفّر المفتاحَين العام والخاص لربط Firebase بنطاق تطبيق العميل.

Google Cloud Platform: توفّر هذه المنصة مفاتيح واجهة برمجة التطبيقات المستخدَمة في كلّ من "منصة خرائط Google" وFirebase، بالإضافة إلى القيود المفروضة على النطاق باستخدام مفتاح "خرائط Google".

يمكنك الاطّلاع على طريقة عملها معًا في مخطط البنية التالي:

نظرة عامة على بنية النظام

عند استخدام App Check و"منصة خرائط Google"، تعمل العناصر التالية معًا لتحديد ما إذا كانت الطلبات واردة من تطبيق ومستخدم صالحَين، وذلك باستخدام شهادة مقدَّمة من مقدّم شهادات، وفي هذه الحالة reCAPTCHA.

يتم ذلك من خلال استخدام حزمة تطوير البرامج (SDK) الخاصة بخدمة App Check التي يوفّرها Firebase، والتي تتحقّق من صحة التطبيق الذي يتم استدعاؤه ثم تقدّم رمزًا مميزًا للتطبيق يتم من خلاله إجراء الطلبات اللاحقة إلى Google Maps Platform Javascript API. في المقابل، تتحقّق Google Maps Platform JavaScript API من صحة الرمز المميّز المقدَّم باستخدام Firebase للتأكّد من أنّه وارد من النطاق الصحيح ومن خلال مقدّم خدمة التصديق من مستخدم صالح.

يمكنك العثور على مزيد من التفاصيل حول استخدام App Check وMaps JavaScript API في الموقع التالي، ويجب التعرّف على الخطوات المطلوبة.

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

3- طريقة الإعداد

إذا لم يكن لديك حساب على Google Cloud، عليك إعداد حساب مع تفعيل الفوترة في البداية. اتّبِع التعليمات لإنشاء هذا الحساب قبل البدء.

إعداد "منصة خرائط Google"

إذا لم يكن لديك حساب على Google Cloud Platform ومشروع مفعَّلة فيه الفوترة، يُرجى الاطّلاع على دليل البدء باستخدام "منصة خرائط Google" لإنشاء حساب فوترة ومشروع.

  1. في Cloud Console، انقر على القائمة المنسدلة الخاصة بالمشروع واختَر المشروع الذي تريد استخدامه في هذا الدرس العملي.

  1. فعِّل واجهات برمجة التطبيقات وحِزم تطوير البرامج (SDK) المطلوبة لهذا الدرس العملي من Google Maps Platform في Google Cloud Marketplace. لإجراء ذلك، اتّبِع الخطوات الواردة في هذا الفيديو أو هذه المستندات.
  2. أنشئ مفتاح واجهة برمجة التطبيقات في صفحة بيانات الاعتماد في Cloud Console. يمكنك اتّباع الخطوات الواردة في هذا الفيديو أو هذه المستندات. تتطلّب جميع الطلبات المُرسَلة إلى "منصة خرائط Google" مفتاح واجهة برمجة تطبيقات.

المتطلبات الأخرى لهذا الدرس التطبيقي حول الترميز

لإكمال هذا الدرس العملي، ستحتاج إلى الحسابات والخدمات والأدوات التالية:

  • معرفة أساسية بلغات JavaScript وHTML وCSS
  • حساب على Google Cloud تم تفعيل الفوترة فيه (كما هو موضّح)
  • مفتاح واجهة برمجة تطبيقات في Google Maps Platform مع تفعيل Maps JavaScript API (سيتم ذلك أثناء جلسة التدريب العملي).
  • فهم أساسي لاستضافة الويب ونشره (سيتم إرشادك خلال هذه العملية في الدرس التطبيقي). سيتم ذلك من خلال "وحدة تحكّم Firebase" وFirebase Studio.
  • متصفّح ويب لعرض الملفات أثناء العمل عليها

4. إنشاء صفحة في Firebase Studio

لا يفترض هذا الدرس العملي أنّ لديك تطبيقًا تم إنشاؤه من قبل، بل يستخدم Firebase Studio لإنشاء صفحة لاستضافة تطبيق "الخرائط" ونشره على Firebase لأغراض الاختبار. إذا كان لديك تطبيق حالي، يمكنك أيضًا استخدامه بدلاً من ذلك، مع تغيير نطاقات المضيف ومقتطفات الرموز ومفاتيح واجهة برمجة التطبيقات المناسبة لضمان التنفيذ الصحيح.

انتقِل إلى Firebase Studio (يتطلّب حسابًا على Google) وأنشئ تطبيق HTML بسيط جديدًا. قد تحتاج إلى النقر على الزر "عرض جميع النماذج" لعرض هذا الخيار أو يمكنك النقر على هذا الرابط للوصول المباشر.

صورة تعرض نموذج 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>

عند تشغيل هذا الرمز، من المفترض أن تظهر صفحة تعرض خريطة للتطبيق الذي يعمل كما هو موضّح في الصورة، ولكن!

صورة تعرض تطبيقًا قيد التشغيل

عند تحميل الصفحة، سيتم عرض خطأ لأنّها ستتطلّب مفتاح واجهة برمجة التطبيقات على "منصة خرائط Google" في الصفحة، وسيتمّ إضافته في قسم لاحق.

صورة تعرض الإشعار &quot;حدث خطأ&quot;.

يمكن الاطّلاع على رسالة الخطأ الفعلية في وحدة تحكّم الويب في Firebase Studio.

رسالة خطأ المفتاح غير صالح

لحلّ هذه المشكلة، علينا إضافة مفتاح واجهة برمجة تطبيقات إلى الصفحة. مفتاح واجهة برمجة التطبيقات هو الطريقة التي يتم من خلالها ربط الصفحة وتنفيذ Maps JavaScript API. وهي أيضًا منطقة استغلال، إذ يجب أن يتم تضمينها في الصفحة بطريقة غير مشفّرة، حيث يمكن أخذ مفتاح واجهة برمجة التطبيقات واستخدامه في مواقع إلكترونية مختلفة.

إحدى طرق الحماية هي استخدام قيود التطبيق، إما من خلال نوع التطبيق المستخدَم أو من خلال النطاق المُحيل أو عنوان IP الذي يتم طلبه. يمكنك الاطّلاع على مزيد من المعلومات حول أفضل الممارسات على الموقع الإلكتروني التالي:

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

أو من خلال استخدام طلبات مباشرة من سطر الأوامر أو الخادم، أو التطبيقات التي لا يمكنها توفير إحالة أو تتبُّعها، وبالتالي قد تشكّل ثغرة أمنية.

5- إنشاء تطبيق Firebase

يتم استخدام Firebase لتوفير وظيفة ربط مقدّم خدمة التصديق بالتحقّق من ما يلي:

  • تنشأ الطلبات من تطبيقك الأصلي
  • أن تنشأ الطلبات من جهاز وجلسة مستخدم أصليين لم يتم التلاعب بهما.

في هذا الدرس العملي، سيتم استخدام الإصدار الثالث من reCAPTCHA كموفّر لشهادة التصديق هذه.

إنشاء تطبيق Firebase واستضافته

انتقِل إلى https://firebase.google.com/ وأنشئ مشروعًا جديدًا في Firebase من خلال الرابط "الانتقال إلى وحدة التحكّم".

صورة تعرض رابط Console

أنشِئ مشروعًا جديدًا من خلال النقر على المنطقة التالية.

أنشِئ مشروعًا جديدًا على Firebase.

اختَر اسمًا للمشروع، مثل مشروع "التحقّق من التطبيق"، وليس من الضروري أن يكون الاسم هو نفسه الذي تم استخدامه من قبل لأنّ هذا الاسم مخصّص للرجوع إليه فقط، ويمكن تعديل الاسم الفعلي للمشروع أسفل النص مباشرةً، وسيتألف من الاسم الذي أدخلته، وإذا لم يكن فريدًا، سيتم إضافة رقم إليه.

صورة تعرض تفاصيل إدخال اسم المشروع

إذا طُلب منك إضافة خدمات أخرى (مثل "إحصاءات Google") إلى تطبيقك، يمكنك قبولها أو رفضها، ولكنّها غير مطلوبة في هذا الدرس العملي، لذا يمكنك عدم إضافتها.

انقر على الزر "إنشاء مشروع" وانتظِر إلى أن يتم إنشاء المشروع. سيصلك إشعار عند اكتمال العملية.

صورة تعرض مربّع حوار إنشاء مشروع.

انقر على "متابعة" عندما يصبح هذا المشروع جاهزًا لبدء التفاعل معه.

صورة تعرض مربّع حوار اكتمال المشروع

من الصفحة الرئيسية، يمكنك بعد ذلك اختيار البدء من خلال إضافة Firebase إلى تطبيقك واختيار خيار الويب.

ابدأ بإضافة

اختَر إعداد "استضافة Firebase" لموقعك الإلكتروني لتحديد مكان تخزين الملفات بعد نشرها (يمكنك استخدام خيارك الخاص لموقعك الإلكتروني الفعلي، ولكن لتنفيذ هذا الدرس العملي، عليك النشر إلى "استضافة Firebase").

سجِّل التطبيق الجديد.

انقر على "تسجيل التطبيق" لإنشاء التطبيق. بعد ذلك، ستأخذ النص البرمجي الذي تم إنشاؤه وتستخدمه للإشارة إلى المشروع في Firebase من تطبيق الويب.

سيتم استخدام رمز إعداد Firebase في علامة التبويب التالية في التطبيق لربط Firebase وواجهات برمجة التطبيقات للخرائط معًا، لذا من المفيد نسخه من قسم "استخدام علامة البرنامج النصي". عليك لصق هذا الرمز في ملف index.html الخاص بالمشروع.

علامة النص البرمجي التي يجب تضمينها في الصفحة

انقر على "التالي" للأقسام الأخرى، ثم اطّلِع على التطبيق الذي تم إنشاؤه في قسم إعدادات المشروع بالموقع الإلكتروني.

إذا كنت بحاجة إلى الرجوع والعثور على تفاصيل الإعداد في وقت لاحق، يمكنك أيضًا العثور على تفاصيل التطبيق من خلال زر "الإعدادات"، كما هو موضّح:

عنصر قائمة &quot;إعدادات المشروع&quot;

قبل مغادرة هذا القسم، عليك تدوين نطاق الموقع الإلكتروني الذي تم إنشاؤه باستخدام ميزة "استضافة Firebase" لاستخدامه لاحقًا مع reCAPTCHA. يتيح ذلك ربط اسم الموقع الإلكتروني بمقدّم خدمة الإقرار، ما يعني أنّه سيتم التحقّق من الطلبات الواردة من هذا الموقع الإلكتروني فقط.

انتقِل إلى قسم الاستضافة من اختصارات المشروع أو قائمة "إنشاء" على يمين الصفحة

صورة تعرض اختصار &quot;الاستضافة&quot;. أو صورة تعرض قائمة إنشاء الاستضافة

ومن القسم، ابحث عن النطاق الذي تم إنشاؤه للتطبيق. قد تحتاج إلى النقر على بعض الشاشات لإعدادها إذا لم يسبق لك ذلك.

صورة تعرض مربّع حوار نطاق الاستضافة.

6. مفاتيح واجهة برمجة التطبيقات الآمنة

انتقِل إلى Cloud Console باستخدام الحساب نفسه الذي تستخدم فيه Firebase للاطّلاع على المشروع الذي تم إنشاؤه.

رابط

صورة تعرض رابط Cloud Console

إذا كان لديك مشاريع متعددة، قد تحتاج إلى استخدام القائمة المنسدلة أو مربّع البحث لاختيار المشروع الصحيح، مع اسم مشروعك على Firebase.

صورة تعرض قائمة &quot;اختيار المشروع&quot;

سيؤدي ذلك إلى فتح المشروع الذي تم إنشاؤه حديثًا. ستضيف الآن Maps JavaScript API إلى هذا المشروع حتى يمكن استخدامه ضمن المشروع، بما في ذلك حصر استخدامه على مفتاح API ونطاق استضافة محدّدَين.

صورة تعرض صفحة الترحيب في &quot;المشروع&quot;

استخدِم القائمة على يمين الصفحة لتفعيل واجهات Maps API في المشروع. انقر على خيار "واجهات برمجة التطبيقات والخدمات" ثم على "واجهات برمجة التطبيقات والخدمات المفعّلة".

صورة تعرض قائمة &quot;تفعيل واجهات برمجة التطبيقات&quot; المستخدَمة

انقر على خيار "تفعيل واجهات برمجة التطبيقات والخدمات".

صورة تعرض قائمة &quot;اختيار واجهات برمجة التطبيقات المراد تفعيلها&quot;

أدخِل "Maps JavaScript API" في مربّع البحث.

صورة تعرض مربّع البحث في واجهة برمجة التطبيقات

اختَر النتيجة المطابقة.

صورة تعرض مربّع &quot;اختيار واجهة برمجة التطبيقات المطابقة&quot;

بعد ذلك، انقر على "تفعيل" في واجهة برمجة التطبيقات لإضافتها إلى مشروعك (ربما تم إجراء ذلك من قبل إذا كنت قد استخدمت هذا المشروع سابقًا).

صورة تعرض المربّع &quot;تفعيل واجهة برمجة التطبيقات المطابقة&quot;

بعد تفعيل هذا الخيار، يمكنك اختيار إضافة مفتاح واجهة برمجة تطبيقات وتقييده، ولكن سيتم تخطّي هذه الخطوة في الوقت الحالي.

باستخدام خيارات القائمة اليمنى مرة أخرى، ارجع إلى قسم "واجهة برمجة التطبيقات والخدمات" واختَر مفتاح المتصفّح الذي تم إنشاؤه لك.

صورة تعرض كيفية حظر واجهات برمجة التطبيقات

أضِف Maps JavaScript API إلى أحد قيود واجهة برمجة التطبيقات.

اختَر Maps API للتصفية.

بالنسبة إلى المفاتيح في تطبيق مباشر، عليك أيضًا وضع قيود على النطاق الذي يستضيف التطبيق، ويمكنك إجراء ذلك الآن باستخدام النطاق الذي تم إنشاؤه لك في Firebase. يجب أيضًا إضافة /* إلى نهاية النطاق للتأكّد من أنّه يشمل جميع المسارات ضمنه.

النطاق الذي سيتمّ الحصر عليه.

يمكنك العثور على مزيد من التفاصيل حول تفعيل هذا الخيار في الموقع الجغرافي التالي للحصول على مزيد من المعلومات حول تقييد مفاتيح واجهة برمجة التطبيقات.

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

7. إنشاء أسرار reCAPTCHA

الخطوة التالية هي إنشاء مشروع reCAPTCHA لتوفير الشهادة والمفاتيح لكل من العميل والخادم.

انتقِل إلى موقع reCAPTCHA الإلكتروني على https://www.google.com/recaptcha/ وانقر على زر "البدء".

صورة تعرض صفحة &quot;بدء استخدام reCAPTCHA&quot;

بعد ذلك، سجِّل موقعًا إلكترونيًا جديدًا، وتأكَّد من إدخال النطاق الصحيح لحظر الوصول إليه.

صورة تعرض تسجيل موقع إلكتروني في reCAPTCHA

احرِص أيضًا على اختيار مشروع Google Cloud نفسه الذي أنشأه Firebase في حال كان لديك أكثر من مشروع.

سيؤدي ذلك إلى إنشاء مفتاحَين، أحدهما مفتاح سري ستدخله في وحدة تحكّم Firebase، ويجب عدم وضعه أبدًا في أي صفحة أو تطبيق يمكن عرضه بشكل علني، والآخر مفتاح موقع إلكتروني ستستخدمه في تطبيق الويب.

صورة تعرض صفحة مفاتيح reCAPTCHA.

يُرجى إبقاء هذه الصفحة مفتوحة لأنّك ستحتاج إليها. انقر على زر نسخ المفتاح السري (Secret Key)، ثم ارجع إلى موقع Firebase الإلكتروني.

8. إضافة reCAPTCHA إلى Firebase

في "وحدة تحكّم المشرف" في Firebase، انتقِل إلى عناصر القائمة على يمين الصفحة. ضمن عنصر القائمة إنشاء، اختَر App Check.

صورة تعرض قائمة إنشاء الاستضافة

لا يمكن تفعيل قائمة الخدمات إلا بعد تسجيل تطبيق (تم إنشاء هذا التطبيق سابقًا عند إضافة الاستضافة إلى الموقع الإلكتروني)، انقر على "البدء" إذا كنت بحاجة إلى إعداد ذلك.

انقر على علامة التبويب "التطبيق" (App) وافتح تطبيق الويب (Web app)، ثم أدخِل الرمز السري الذي نسخته من موقع reCAPTCHA الإلكتروني وانقر على "حفظ" (Save).

صورة تعرض عملية إدخال الرمز السري

من المفترض أن تظهر الآن علامة صح خضراء بجانب مزوّد reCAPTCHA. يمكن لتطبيق الويب هذا الآن استخدام reCAPTCHA لإثبات ما إذا كان المستخدم أو الموقع الإلكتروني يستدعي الخدمة بشكل صحيح.

علامة اختيار خضراء تشير إلى أنّ reCAPTCHA مفعّلة

في علامة التبويب "واجهات برمجة التطبيقات"، من المفترض أن يظهر الآن أنّ واجهة برمجة التطبيقات على "منصة خرائط Google" نشطة ولكنها غير مفروضة.

خدمة App Check نشطة ولكنّها غير مفروضة.

لقد ربطت الآن مفتاح reCAPTCHA السري بمشروع Firebase ويمكنك الآن الانتقال وإضافة الرمز إلى صفحة الويب لمطابقة مفتاح الموقع الإلكتروني مع مقدّم الخدمة المناسب لاستخدامه مع تطبيق "خرائط Google".

تتحقّق خدمة reCAPTCHA من مفتاح الموقع الإلكتروني للتأكّد من مطابقته للمفتاح السري. وبعد إتمام ذلك، تؤكّد أنّ الصفحة التي يتم استدعاؤها صحيحة، وتوفّر خدمة App Check رمزًا مميزًا يمكن استخدامه في الطلبات اللاحقة إلى Maps JavaScript API. وبدون هذه الشهادة، لن يتم تقديم الرمز المميز ولن يمكن التحقّق من صحة الطلبات.

9- أضِف عملية إثبات الملكية إلى الصفحة ونفِّذها.

ارجع إلى وحدة تحكّم السحابة الإلكترونية وانسخ مفتاح واجهة برمجة التطبيقات المطلوب استخدامه لواجهة برمجة التطبيقات Maps API.

يمكنك العثور على ذلك من القائمة الجانبية في وحدة التحكّم، ضِمن القائمة الجانبية "واجهات برمجة التطبيقات والخدمات"، وضِمن خيار "بيانات الاعتماد".

صورة تعرض قائمة &quot;بيانات الاعتماد&quot;

يمكنك من هنا اختيار مفتاح المتصفّح الحالي (مع العلم أنّه يمكنك استخدام مفتاح حالي مختلف أو إنشاء مفتاح جديد).

صورة تعرض خيار &quot;مفتاح المتصفّح الحالي&quot;.

انقر على زر عرض المفتاح وانسخ المفتاح من نافذة مربّع الحوار المعروضة.

ارجع إلى مشروع Firebase Studio الذي تم فيه فتح صفحة HTML التي أنشأتها سابقًا. يمكنك الآن إضافة مفتاح واجهة برمجة التطبيقات إلى الصفحة لتفعيل Maps API في المكان الذي تتضمّن فيه الصفحة "YOUR_API_KEY".

تعديل مفتاح واجهة برمجة التطبيقات

بعد إعادة تشغيل الصفحة، ستظهر رسالة خطأ مختلفة.

رسالة الخطأ &quot;لا يُسمح بالمُحيل&quot;

وهذا يعني أنّ نطاق التطوير الذي تستضيف الصفحة منه غير مسموح به (لقد أضفنا النطاق الذي تم نشره فقط). سنحتاج إلى نشر هذا الموقع الإلكتروني على النطاق الصحيح باستخدام "استضافة Firebase". يمكنك الحصول على مزيد من التفاصيل في الموقع الجغرافي التالي:

النشر باستخدام خدمة استضافة Firebase

وهذا الفيديو

إنشاء تطبيقات الويب على Firebase واختبارها ونشرها بشكل أسرع في Project IDX

خطأ في عدم تفعيل الفوترة

يمكن العثور على مزيد من التفاصيل ضمن أخطاء تحميل الخريطة على الموقع الإلكتروني لواجهة برمجة تطبيقات JavaScript لـ "خرائط Google".

إذا ظهرت لك رسالة الخطأ RefererNotAllowedMapError، يمكنك حلّ هذه المشكلة من خلال نشر الصفحة على النطاق الصحيح.

ارجع إلى Firebase Studio وانقر على رمز "Firebase Studio" (قد يكون هذا الرمز في أقصى اليمين أو أقصى اليسار حسب الخيار الذي أعددته) لفتح خيارات الاستضافة.

صورة تعرض رمز Firebase Studio.

في هذا الدرس العملي، عليك بعد ذلك "استضافة التطبيق باستخدام Firebase" لربط مثيل Firebase بتطبيق Android Studio.

خيار &quot;الاستضافة باستخدام Firebase&quot;

بعد ذلك، انقر على "مصادقة Firebase" لبدء عملية المصادقة، ما يتيح لحسابك إمكانية إعداد الاستضافة تلقائيًا باستخدام الخلفية من داخل الاستوديو.

صورة تعرض خيار &quot;مصادقة Firebase&quot;.

اتّبِع التعليمات الواردة في نافذة الأوامر للسماح بعملية النشر.

صورة تعرض تعليمات المصادقة

اتّبِع التعليمات الظاهرة على الشاشة (بما في ذلك فتح نافذة جديدة) وانسخ رمز التفويض في المكان المطلوب والصِقه في نافذة الأوامر في "استوديو Firebase".

صورة تعرض رمز تفويض Firebase.

يمكنك الحصول على مزيد من التفاصيل حول هذه العملية من خلال الرابط التالي:

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

بعد الانتهاء من ذلك، يمكنك النقر على "تهيئة استضافة Firebase" لربط المشروع بمشروع Firebase.

اختَر "استخدام مشروع حالي" واختَر المشروع الذي أنشأته في القسم السابق. اقبل بقية الإعدادات التلقائية (قد يختلف مثالك حسب الاسم الذي تختاره عند إعداد المشروع).

إعداد مشروع استضافة Firebase

ارجع إلى "طريقة العرض في المستكشف" واستبدِل ملف index.html الذي تم إنشاؤه في الدليل العام بالملف الذي كان لديك في الدليل الجذر.

صورة تعرض بنية ملف الاستضافة

يمكنك الآن الرجوع إلى الشريط الجانبي في Firebase Studio ونشر الموقع الإلكتروني في مرحلة الإنتاج.

صورة تعرض عملية النشر في مرحلة الإنتاج

سيؤدي ذلك إلى عرض خطوات النشر في وحدة التحكّم.

صورة تعرض خطوات النشر

افتح الموقع الإلكتروني الذي تم نشره من "عنوان URL للاستضافة" المعروض (يظهر هنا على أنّه https://my-app-check-project.web.app/ ولكن سيكون مختلفًا لمشروعك).

سيعرض التطبيق الآن الخريطة على الصفحة أثناء عمل واجهات برمجة التطبيقات للنطاقات المستخدَمة.

صورة تعرض قائمة إنشاء الاستضافة

أصبحت هناك الآن صفحة تعمل، مع وضع قيود على نوع واجهات برمجة التطبيقات التي يمكن استخدامها مع مفتاح واجهة برمجة التطبيقات، وكذلك النطاقات التي يمكن استخدام مفتاح واجهة برمجة التطبيقات فيها. الخطوة التالية هي حصر إمكانية الوصول على هذا النطاق فقط. لإجراء ذلك، عليك إضافة قسم نص Firebase الذي تم إنشاؤه سابقًا لتأمين الصفحة باستخدام App Check. سيتم ذلك في القسم التالي.

10. صفحة آمنة

في حين أنّ الصفحة الحالية تحمي مفتاح واجهة برمجة التطبيقات للنطاق، إلا أنّها لا تضيف خطوة التصديق للتأكّد من أنّ التطبيق الصحيح والشخص المناسب يستخدمان المفتاح. قد يظل بإمكان الجهة المسيئة سرقة المفتاح واستخدامه. لإيقاف ذلك، يجب إضافة إعدادات 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,
       });

أخيرًا، اربط دالة بعنصر التحكّم في الخريطة باستخدام دالة الإعدادات في مكتبة 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.

جارٍ التحقّق من أنّ ميزة التتبُّع مفعَّلة.

سيؤدي فتح النافذة الآن إلى إظهار أنّ البرامج ترسل طلبات وأنّ عملية التصديق تعمل (يظهر ذلك من خلال طلبات "تم التحقّق منها" باللون الأزرق الداكن على الرسم البياني). ستعرض الطلبات الأخرى مكالمات خلال مرحلة التطوير قبل اكتمال عملية التحقّق.

رسم بياني يعرض الطلبات التي تم التحقّق منها

بعد التأكّد من أنّ العملاء يعملون بشكل سليم، يمكن تفعيل عملية التنفيذ على الموقع الإلكتروني للتأكّد من عدم إمكانية استخدام مفاتيح واجهة برمجة التطبيقات من تطبيق عميل غير صالح. انقر على الزر "فرض" لبدء عملية الفرض.

صورة تعرض زرّ التنفيذ

سيؤدي النقر على هذا الخيار إلى ظهور علامة تحذير كبيرة توضّح أنّ ذلك سيؤدي إلى إغلاق تطبيقك. وفي الواقع، لن يتم تنفيذ ذلك إلا عندما تتأكّد من أنّ جميع عملائك لديهم المفاتيح الصحيحة وأنّهم يعملون، وإلا قد لا يتمكّن المستخدمون من الوصول إلى الموقع الإلكتروني.

صورة تعرض مربّع حوار التنفيذ.

وقد يستغرق تنفيذها بعض الوقت أيضًا. يتم عرض هذه الملاحظة على الشاشة، وإذا اختبرت عملية التنفيذ على الفور، قد لا يكون قد تم نشرها بعد.

يستغرق تطبيقها 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>

بعد إكمال هذه الخطوات وإدخال مفتاح واجهة برمجة التطبيقات الصحيح، من المفترض أن يظهر لك مربّع الخطأ الرمادي التالي عند طلب الصفحة (استخدِم yourdomain/nocheck.html).

حدث خطأ.

عند التحقّق من وحدة التحكّم، من المفترض أن تظهر لك رسالة خطأ مشابهة لما يلي:

رسالة الخطأ &quot;App Check غير صالح&quot;

تمكّنت خدمة "التحقّق من التطبيق" بنجاح من حظر طلب الخريطة على الصفحة لأنّها لم تعُد تتلقّى رمزًا مميزًا من خدمة "التحقّق من التطبيق" للموقع الإلكتروني الذي تم فرض القيود عليه.

12. تهانينا!

تهانينا، لقد نجحت في تفعيل خدمة App Check على موقعك الإلكتروني.

صفحة تعرض التطبيق الذي يتم العمل عليه

لقد أنشأت بنجاح تطبيقًا يستخدم ميزة "فحص التطبيقات من Firebase" للتأكّد من أنّ الطلبات واردة من نطاق ومستخدم صالحَين.

ما تعلّمته

  • كيفية استخدام Firebase Studio لاستضافة صفحة ويب ونشرها
  • كيفية استخدام Cloud Console لتفعيل واجهات Google Maps Platform API وتأمينها
  • كيفية استخدام reCAPTURE لإنشاء مفاتيح يمكن استخدامها لإثبات صحة الطلبات
  • كيفية استخدام خدمة App Check من Firebase ودمجها في Maps JavaScript API
  • تعرَّف على كيفية فرض عمليات التحقّق من المواقع الإلكترونية المحمية ومراقبتها باستخدام Firebase Studio.

ما هي الخطوات التالية؟