إدارة "قواعد أمان Firebase" ونشرها

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

بغض النظر عن الأداة المستخدمة لاستدعاءها، فإن واجهة برمجة تطبيقات الإدارة:

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

استخدام واجهة سطر الأوامر في Firebase

باستخدام واجهة سطر الأوامر في Firebase، يمكنك تحميل المصادر المحلية ونشر الإصدارات. تتيح لك "حزمة محاكي Firebase المحلية" من واجهة سطر الأوامر إمكانية إجراء اختبار محلي كامل للمصادر.

ويتيح لك استخدام واجهة سطر الأوامر (CLI) إبقاء قواعدك تحت إمكانية التحكم في الإصدار من خلال رمز التطبيق ونشر القواعد كجزء من عملية النشر الحالية.

إنشاء ملف إعداد

عند إعداد مشروعك في Firebase باستخدام واجهة سطر الأوامر في Firebase، يمكنك إنشاء ملف إعداد .rules في دليل مشروعك. استخدِم الأمر التالي لبدء إعداد مشروعك على Firebase:

Cloud Firestore

// Set up Firestore in your project directory, creates a .rules file
firebase init firestore

قاعدة بيانات الوقت الفعلي

// Set up Realtime Database in your project directory, creates a .rules file
firebase init database

Cloud Storage

// Set up Storage in your project directory, creates a .rules file
firebase init storage

تعديل القواعد وتعديلها

يمكنك تعديل مصدر القواعد مباشرةً في ملف الإعداد .rules.

تأكَّد من أنّ أي تعديلات تُجريها في واجهة سطر الأوامر في Firebase تظهر في وحدة تحكُّم Firebase، أو أن تُجري تعديلاتك باستمرار باستخدام وحدة تحكُّم Firebase أو واجهة سطر الأوامر في Firebase. بخلاف ذلك، يمكنك استبدال أي تحديثات تم إجراؤها في وحدة تحكم Firebase.

اختبار التحديثات

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

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

نشر التحديثات

بعد تحديث "القواعد" واختبارها، انشر المصادر في الإنتاج.

بالنسبة إلى قواعد أمان Cloud Firestore، اربط ملفات .rules بقواعد البيانات التلقائية وقواعد البيانات الإضافية المسماة من خلال مراجعة ملف firebase.json وتعديله.

استخدم الأوامر التالية لنشر القواعد وحدها بشكل انتقائي أو لنشرها كجزء من عملية النشر العادية.

Cloud Firestore

// Deploy rules for all databases configured in your firebase.json
firebase deploy --only firestore:rules
// Deploy rules for the specified database configured in your firebase.json firebase deploy --only firestore:<databaseId>

قاعدة بيانات الوقت الفعلي

// Deploy your .rules file
firebase deploy --only database

Cloud Storage

// Deploy your .rules file
firebase deploy --only storage

استخدام "وحدة تحكُّم Firebase"

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

تعديل القواعد وتعديلها

  1. افتح وحدة تحكُّم Firebase واختَر مشروعك.
  2. بعد ذلك، اختَر قاعدة بيانات في الوقت الفعلي أو Cloud Firestore أو مساحة التخزين من شريط التنقّل الخاص بالمنتج، ثم انقر على القواعد للانتقال إلى "محرِّر القواعد".
  3. عدِّل القواعد مباشرةً في المحرِّر.

اختبار التحديثات

بالإضافة إلى اختبار البنية في واجهة مستخدم أداة التعديل، يمكنك اختبار سلوك "القواعد الدلالية"، باستخدام قاعدة بيانات مشروعك وموارد التخزين، مباشرةً في وحدة تحكُّم Firebase، باستخدام ساحة القواعد. افتح شاشة ملعب القواعد في محرّر القواعد وعدِّل الإعدادات وانقر على تشغيل. ابحث عن رسالة التأكيد في أعلى المحرِّر.

نشر التحديثات

بعد التأكّد من أنّ التعديلات على مستوى توقعاتك، انقر على نشر.

استخدام SDK للمشرف

ويمكنك استخدام حزمة تطوير البرامج (SDK) للمشرف لقواعد Node.js. باستخدام هذا الوصول الآلي، يمكنك:

  • يمكنك تنفيذ أدوات مخصصة ونصوص برمجية ولوحات بيانات ومسارات CI/CD لإدارة القواعد.
  • إدارة القواعد بسهولة أكبر على مستوى مشاريع متعددة في Firebase

عند تعديل القواعد آليًا، من المهم جدًا تجنُّب إجراء تغييرات غير مقصودة على عناصر التحكّم في الوصول إلى تطبيقك. اكتب رمز حزمة تطوير البرامج (SDK) للمشرف في مقدّمة أولوياتك، خاصةً عند تعديل القواعد أو نشرها.

يُرجى العِلم أنّ نشر إصدارات "قواعد أمان Firebase" يستغرق فترة تصل إلى عدة دقائق. عند استخدام SDK للمشرف لنشر القواعد، احرص على تجنب حالات السباق التي يعتمد فيها تطبيقك بشكل فوري على القواعد التي لم تكتمل عملية نشرها بعد. إذا كانت حالة الاستخدام تتطلب إجراء تحديثات متكررة لقواعد التحكّم في الوصول، ننصحك بالتفكير في حلول تستخدم Cloud Firestore، والتي تم تصميمها للحدّ من حالات السباق على الرغم من التحديثات المتكرّرة.

لاحظ أيضًا هذه الحدود:

  • يجب أن تكون القواعد أصغر من 256 كيبيبايت من نص بترميز UTF-8 عند إتمامها بالتسلسل.
  • يمكن أن يحتوي المشروع على ما لا يزيد عن 2500 مجموعة قواعد منشورة. وعند بلوغ هذا الحدّ الأقصى، عليك حذف بعض مجموعات القواعد القديمة قبل إنشاء مجموعات جديدة.

إنشاء مجموعات قواعد Cloud Storage أو Cloud Firestore ونشرها

يمكن أن يشتمل سير العمل النموذجي لإدارة قواعد الأمان باستخدام SDK للمشرف على ثلاث خطوات منفصلة:

  1. إنشاء مصدر ملف القواعد (اختياري)
  2. إنشاء مجموعة قواعد
  3. إصدار مجموعة القواعد الجديدة أو نشرها

توفِّر حزمة تطوير البرامج (SDK) طريقة لدمج هذه الخطوات في طلب واحد من واجهة برمجة التطبيقات لقواعد الأمان في Cloud Storage وCloud Firestore. على سبيل المثال:

    const source = `service cloud.firestore {
      match /databases/{database}/documents {
        match /carts/{cartID} {
          allow create: if request.auth != null && request.auth.uid == request.resource.data.ownerUID;
          allow read, update, delete: if request.auth != null && request.auth.uid == resource.data.ownerUID;
        }
      }
    }`;
    // Alternatively, load rules from a file
    // const fs = require('fs');
    // const source = fs.readFileSync('path/to/firestore.rules', 'utf8');

    await admin.securityRules().releaseFirestoreRulesetFromSource(source);

وينطبق هذا النمط نفسه على قواعد Cloud Storage التي تتضمّن releaseFirestoreRulesetFromSource().

بدلاً من ذلك، يمكنك إنشاء ملف القواعد كعنصر في الذاكرة، وإنشاء مجموعة قواعد، ونشر مجموعة القواعد بشكل منفصل للتحكّم بشكل أكبر في هذه الأحداث. على سبيل المثال:

    const rf = admin.securityRules().createRulesFileFromSource('firestore.rules', source);
    const rs = await admin.securityRules().createRuleset(rf);
    await admin.securityRules().releaseFirestoreRuleset(rs);

تعديل مجموعات قواعد قاعدة بيانات الوقت الفعلي

لتعديل مجموعات قواعد قاعدة بيانات الوقت الفعلي باستخدام حزمة تطوير البرامج (SDK) للمشرف، استخدِم الطريقتَين getRules() وsetRules() للطريقة admin.database. يمكنك استرداد مجموعات القواعد بتنسيق JSON أو كسلسلة تحتوي على تعليقات مضمنة.

لتعديل مجموعة قواعد:

    const source = `{
      "rules": {
        "scores": {
          ".indexOn": "score",
          "$uid": {
            ".read": "$uid == auth.uid",
            ".write": "$uid == auth.uid"
          }
        }
      }
    }`;
    await admin.database().setRules(source);

إدارة مجموعات القواعد

للمساعدة في إدارة مجموعات القواعد الكبيرة، تتيح لك "SDK للمشرف" إدراج جميع القواعد الحالية باستخدام admin.securityRules().listRulesetMetadata. على سبيل المثال:

    const allRulesets = [];
    let pageToken = null;
    while (true) {
      const result = await admin.securityRules().listRulesetMetadata(pageToken: pageToken);
      allRulesets.push(...result.rulesets);
      pageToken = result.nextPageToken;
      if (!pageToken) {
        break;
      }
    }

بالنسبة إلى عمليات النشر الكبيرة جدًا التي تصل إلى الحدّ الأقصى المسموح به لمجموعة القواعد البالغ 2, 500 بمرور الوقت، يمكنك إنشاء منطق لحذف أقدم القواعد في دورة زمنية ثابتة. على سبيل المثال، لحذف جميع مجموعات القواعد التي تم نشرها لأكثر من 30 يومًا:

    const thirtyDays = new Date(Date.now() - THIRTY_DAYS_IN_MILLIS);
    const promises = [];
    allRulesets.forEach((rs) => {
      if (new Date(rs.createTime) < thirtyDays) {
        promises.push(admin.securityRules().deleteRuleset(rs.name));
      }
    });
    await Promise.all(promises);
    console.log(`Deleted ${promises.length} rulesets.`);

استخدام واجهة برمجة تطبيقات REST

تُناسب الأدوات الموضَّحة أعلاه سير العمل المتنوّع، بما في ذلك إدارة "قواعد أمان Firebase" لقواعد بيانات Cloud Firestore المتعدّدة في مشروعك، ولكن قد تحتاج إلى إدارة "قواعد أمان Firebase" ونشرها باستخدام واجهة برمجة التطبيقات للإدارة (API) نفسها. تمنحك واجهة برمجة تطبيقات الإدارة أكبر قدر من المرونة.

لاحظ أيضًا هذه الحدود:

  • يجب أن تكون القواعد أصغر من 256 كيبيبايت من نص بترميز UTF-8 عند إتمامها بالتسلسل.
  • يمكن أن يحتوي المشروع على ما لا يزيد عن 2500 مجموعة قواعد منشورة. وعند بلوغ هذا الحدّ الأقصى، عليك حذف بعض مجموعات القواعد القديمة قبل إنشاء مجموعات جديدة.

إنشاء مجموعات قواعد Cloud Firestore أو Cloud Storage ونشرها باستخدام REST

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

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

في ما يلي الخطوات النموذجية لإنشاء مجموعة قواعد ونشرها باستخدام واجهة برمجة تطبيقات الإدارة:

  1. إنشاء مصادر ملفات القواعد
  2. إنشاء مجموعة قواعد
  3. اطرح (انشر) مجموعة القواعد الجديدة.

إنشاء مصدر

لنفترض أنّك تعمل في مشروع Firebase واحد (secure_commerce) وتريد نشر قواعد Cloud Firestore المؤمَّنة على قاعدة بيانات في مشروعك باسم east_store.

يمكنك تطبيق هذه القواعد في ملف firestore.rules.

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if false;
    }
  }
}

إنشاء مجموعة قواعد

عليك الآن إنشاء بصمة إصبع بترميز base64 لهذا الملف. يمكنك بعد ذلك استخدام المصدر في هذا الملف لتعبئة الحمولة اللازمة لإنشاء مجموعة قواعد باستخدام طلب REST projects.rulesets.create. يمكنك هنا استخدام الأمر cat لإدراج محتوى firestore.rules في حمولة REST.

ولربط هذه السمة بقاعدة بيانات east_store، عليك ضبط السمة attachment_point على east_store لأغراض التتبُّع.

curl -X POST -d '{
  "source": {
    "files": [
      {
        "content": "' $(cat storage.rules) '",
        "name": "firestore.rules",
        "fingerprint": <sha fingerprint>
      },
    "attachment_point": "firestore.googleapis.com/databases/east_store"
    ]
  }
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/rulesets'

تعرض واجهة برمجة التطبيقات استجابة للتحقّق من الصحة واسمًا لمجموعة القواعد، مثل projects/secure_commerce/rulesets/uuid123.

إصدار (نشر) مجموعة قواعد

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

curl -X POST -d '{
  "name": "projects/secure_commerce/releases/cloud.firestore/east_store"  ,
  "rulesetName": "projects/secure_commerce/rulesets/uuid123"
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/releases'

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

تعديل مجموعات قواعد بيانات الوقت الفعلي باستخدام REST

توفر قاعدة بيانات الوقت الفعلي واجهة REST الخاصة بها لإدارة القواعد. يُرجى الاطّلاع على إدارة قواعد قاعدة بيانات Firebase في الوقت الفعلي من خلال REST.

إدارة مجموعات القواعد باستخدام REST

للمساعدة في إدارة عمليات نشر القواعد الكبيرة، بالإضافة إلى طريقة REST لإنشاء مجموعات القواعد والإصدارات، توفر واجهة برمجة التطبيقات للإدارة (API) طرقًا من أجل:

  • إدراج القواعد والحصول عليها وحذفها
  • إدراج إصدارات القواعد والحصول عليها وحذفها

بالنسبة إلى عمليات النشر الكبيرة جدًا التي تصل إلى الحدّ الأقصى المسموح به لمجموعة القواعد البالغ 2, 500 بمرور الوقت، يمكنك إنشاء منطق لحذف أقدم القواعد في دورة زمنية ثابتة. على سبيل المثال، لحذف جميع مجموعات القواعد التي تم نشرها لأكثر من 30 يومًا، يمكنك استدعاء الطريقة projects.rulesets.list، وتحليل قائمة JSON لعناصر Ruleset في مفاتيح createTime، ثم استدعاء project.rulesets.delete على مجموعات القواعد المقابلة بحلول ruleset_id.

اختبار التحديثات باستخدام REST

وأخيرًا، تسمح لك واجهة برمجة تطبيقات الإدارة بإجراء اختبارات بنائية ودلالية على موارد Cloud Firestore وCloud Storage في مشروعاتك الإنتاجية.

يتكون الاختبار باستخدام هذا المكوّن من واجهة برمجة التطبيقات مما يلي:

  1. تحديد كائن TestSuite JSON لتمثيل مجموعة من TestCase عناصر
  2. إرسال TestSuite
  3. تم عرض TestResult عناصر استنادًا إلى التحليل.

لنُعرِّف كائن TestSuite باستخدام عنصر TestCase واحد في ملف testcase.json. في هذا المثال، نضع مصدر لغة "القواعد" مضمّنًا مع حمولة بيانات REST، إلى جانب مجموعة الاختبار لتشغيل تلك القواعد. نحدد توقع تقييم القواعد، وطلب العميل الذي سيتم اختبار مجموعة القواعد وفقًا له. يمكنك أيضًا تحديد مدى إكمال تقرير الاختبار، وذلك باستخدام القيمة "FULL" للإشارة إلى نتائج لجميع تعبيرات لغة "القواعد" التي يجب تضمينها في التقرير، بما في ذلك التعبيرات التي لم تتم مطابقتها مع الطلب.

 {
  "source":
  {
    "files":
    [
      {
        "name": "firestore.rules",
        "content": "service cloud.firestore {
          match /databases/{database}/documents {
            match /users/{userId}{
              allow read: if (request.auth.uid == userId);
            }
            function doc(subpath) {
              return get(/databases/$(database)/documents/$(subpath)).data;
            }
            function isAccountOwner(accountId) {
              return request.auth.uid == accountId 
                  || doc(/users/$(request.auth.uid)).accountId == accountId;
            }
            match /licenses/{accountId} {
              allow read: if isAccountOwner(accountId);
            }
          }
        }"
      }
    ]
  },
  "testSuite":
  {
    "testCases":
    [
      {
        "expectation": "ALLOW",
        "request": {
           "auth": {"uid": "123"},
           "path": "/databases/(default)/documents/licenses/abcd",
           "method": "get"},
        "functionMocks": [
            {
            "function": "get",
            "args": [{"exact_value": "/databases/(default)/documents/users/123"}],
            "result": {"value": {"data": {"accountId": "abcd"}}}
            }
          ]
      }
    ]
  }
}

يمكننا بعد ذلك إرسال TestSuite هذا للتقييم باستخدام طريقة projects.test.

curl -X POST -d '{
    ' $(cat testcase.json) '
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/rulesets/uuid123:test'

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

إدارة أذونات قواعد الأمان في Cloud Storage على مستوى الخدمات المختلفة

إذا أنشأت "قواعد أمان في Cloud Storage" تستخدِم محتوى مستندات Cloud Firestore لتقييم شروط الأمان، سيُطلب منك في "وحدة تحكُّم Firebase" أو "واجهة سطر الأوامر في Firebase" تفعيل الأذونات لربط المنتجَين.

إذا قررت إيقاف الأمان بين الخدمات المختلفة:

  1. أولاً، قبل إيقاف الميزة، عدِّل قواعدك وإزالة جميع العبارات التي تستخدم دوال "القواعد" للوصول إلى Cloud Firestore. إذا لم يتم تفعيل الميزة، ستؤدّي عمليات تقييم القواعد إلى تعذُّر إرسال طلبات التخزين.

  2. استخدِم صفحة إدارة الهوية وإمكانية الوصول في Google Cloud Console لحذف دور "وكيل خدمة Firestore" في قواعد Firebase" من خلال اتّباع دليل السحابة الإلكترونية لإلغاء الأدوار.

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