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

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

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

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

استخدام Firebase CLI

باستخدام Firebase CLI، يمكنك تحميل المصادر المحلية ونشر الإصدارات. تتيح لك حزمة المحاكي المحلي من Firebase إجراء اختبار محلي كامل للمصادر.Firebase Local Emulator Suite

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

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

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

Cloud Firestore

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

Realtime Database

// 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 CLI تظهر في Firebase console، أو أنّك تجري التعديلات باستمرار باستخدام Firebase console أو Firebase CLI. وإلا، قد يتم استبدال أي تعديلات تم إجراؤها في Firebase وحدة التحكّم.

اختبار التعديلات

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

إذا كنت تستخدم Firebase CLI، فإنّ الحزمة هي أداة ممتازة لاختبار Firebase Security Rules. استخدِم Local Emulator Suite لاختبار التعديلات محليًا وتأكَّد من أنّ Security Rules تعرض السلوك الذي تريده.

نشر التعديلات

بعد تعديل Security Rules واختبارها، انشر المصادر في بيئة الإنتاج.

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

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

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>

Realtime Database

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

Cloud Storage

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

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

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

تعديل قواعدك وتحديثها

  1. افتح Firebase وحدة التحكّم واختَر مشروعك.
  2. بعد ذلك، اختَر Realtime Database أو Cloud Firestore أو Storage من شريط التنقّل بين المنتجات، ثم انقر على Rules للانتقال إلى Security Rules المحرّر.
  3. عدِّل قواعدك مباشرةً في المحرّر.

اختبار التعديلات

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

نشر التعديلات

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

استخدام حزمة SDK للمشرف

يمكنك استخدام Admin SDK لـ Node.js مجموعات القواعد. باستخدام إذن الوصول الآلي هذا، يمكنك إجراء ما يلي:

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

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

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

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

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

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

يمكن أن يتضمّن سير العمل النموذجي لإدارة قواعد الأمان باستخدام Admin 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);

تعديل مجموعات قواعد Realtime Database

لتعديل مجموعات قواعد Realtime Database باستخدام Admin 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);

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

للمساعدة في إدارة مجموعات القواعد الكبيرة، يتيح لك Admin 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;
      }
    }

بالنسبة إلى عمليات النشر الكبيرة جدًا التي تصل إلى الحد الأقصى لمجموعة القواعد البالغ 2500 بمرور الوقت، يمكنك إنشاء منطق لحذف أقدم القواعد في دورة زمنية ثابتة. على سبيل المثال، لحذف جميع مجموعات القواعد التي تم نشرها لأكثر من 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 API

تتلاءم الأدوات الموضّحة أعلاه مع عمليات سير العمل المختلفة، بما في ذلك Firebase Security Rules إدارة لقواعد بيانات Cloud Firestore متعددة في مشروعك، ولكن قد تحتاج إلى إدارة Firebase Security Rules ونشرها باستخدام واجهة برمجة التطبيقات للإدارة نفسها. تمنحك واجهة برمجة التطبيقات للإدارة أكبر قدر من المرونة.

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

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

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

تستخدِم الأمثلة في هذا القسم Firestore Security Rules، على الرغم من أنّها تنطبق أيضًا على Cloud Storage Security Rules.

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

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

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

إنشاء مصدر

لنفترض أنّك تعمل على مشروع Firebase باسم secure_commerce وتريد نشر Cloud Firestore "قواعد الأمان" في Cloud Firestore المحظورة في قاعدة بيانات في مشروعك باسم east_store.Security Rules

يمكنك تنفيذ هذه القواعد في ملف 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 Security Rules يستغرق عدة دقائق للانتشار بالكامل. عند استخدام REST API للإدارة للنشر، احرص على تجنُّب حالات التنافس التي يعتمد فيها تطبيقك على الفور على القواعد التي لم يكتمل نشرها بعد.

تعديل مجموعات قواعد Realtime Database باستخدام REST

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

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

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

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

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

اختبار التعديلات باستخدام REST

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

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

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

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

 {
  "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 Security Rules التي تستخدم خدمات متعددة

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

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

  1. أولاً، قبل إيقاف الميزة، عدِّل قواعدك وأزِل جميع العبارات التي تستخدِم وظائف Security Rules للوصول إلى Cloud Firestore. وإلا، بعد إيقاف الميزة، ستؤدي عمليات تقييم Security Rules إلى فشل طلباتك إلى Storage.

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

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