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

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

بغض النظر عن الأداة المستخدَمة لتشغيلها، تؤدي واجهة برمجة التطبيقات لإدارة الأجهزة إلى ما يلي:

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

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

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

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

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

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

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

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

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

استخدِم الأوامر التالية لنشر 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

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

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

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

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

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

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

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

استخدام 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

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

يُرجى ملاحظة هذه الحدود أيضًا:

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

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

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

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

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

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

إنشاء مصدر

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

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

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

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

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

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

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

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

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

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

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

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

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

أخيرًا، تتيح لك Management API إجراء اختبارات نحوية ودلالية على موارد Cloud Firestore وCloud Storage في مشاريعك المخصّصة للنشر.

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

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

لنحدِّد عنصر TestSuite يتضمّن TestCase واحدًا في ملف testcase.json. في هذا المثال، نمرر مصدر اللغة Rules مضمّنًا مع حمولة REST، إلى جانب مجموعة الاختبار التي يتم تشغيلها على تلك القواعد. نحدّد توقّعًا لتقييم القواعد، وطلب العميل الذي سيتم اختبار مجموعة القواعد وفقًا له. يمكنك أيضًا تحديد مدى اكتمال تقرير الاختبار، باستخدام القيمة "كامل" للإشارة إلى نتائج جميع تعبيرات اللغة 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 الذي تم إرجاعه (الذي يحتوي على حالة الاختبار "نجاح/تعذُّر" وقوائم رسائل debugging و قوائم تعبيرات القواعد التي تمّ زيارتها وتقارير تقييمها) بحالة "نجاح" أنّه تمّ السماح بالوصول بشكل صحيح.

إدارة الأذونات لـ "Cloud Storage Security Rules" على مستوى عدة خدمات

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

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

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

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

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