إدارة "قواعد أمان 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. استخدِم Local Emulator Suite لاختبار تحديثاتك محليًا والتأكّد من أنّ قواعد تطبيقك تعرض السلوك المطلوب.

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

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

بالنسبة إلى "قواعد أمان 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. اختَر بعد ذلك Realtime Database أو 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;
      }
    }

بالنسبة إلى عمليات النشر الكبيرة للغاية التي تصل إلى 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" لقواعد بيانات Cloud Firestore متعددة في مشروعك، ولكن قد تحتاج إلى إدارة "قواعد أمان Firebase" ونشرها باستخدام واجهة برمجة تطبيقات الإدارة نفسها. تمنحك واجهة برمجة التطبيقات management API أكبر قدر من المرونة.

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

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

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

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

تستخدم الأمثلة أيضًا 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.

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

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

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

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

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

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

بالنسبة إلى عمليات النشر الكبيرة للغاية التي تصل إلى 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. في هذا المثال، نمرر مصدر لغة القواعد مضمّنًا مع حمولة 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 لحذف دور "وكيل خدمة قواعد Firebase Firebase" من خلال اتّباع دليل السحابة الإلكترونية لإبطال الأدوار.

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