لغة قواعد الأمان

تستفيد قواعد أمان Firebase من اللغات المرنة والقوية والمخصصة التي تدعم نطاقًا واسعًا من التعقيد والتفاصيل. يمكنك جعل القواعد الخاصة بك محددة أو عامة حسب ما يناسب تطبيقك. تستخدم قواعد قاعدة البيانات في الوقت الفعلي بناء جملة يشبه JavaScript في بنية JSON. تستخدم قواعد Cloud Firestore وCloud Storage لغة تعتمد على Common Expression Language (CEL) ، والتي تعتمد على CEL مع match allow بالبيانات التي تدعم الوصول الممنوح بشكل مشروط.

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

حدد منتجًا لمعرفة المزيد حول قواعده.

تركيب اساسي

سحابة فايرستور

تستخدم قواعد أمان Firebase في Cloud Firestore وCloud Storage البنية والتركيب التاليين:

service <<name>> {
  // Match the resource path.
  match <<path>> {
    // Allow the request if the following conditions are true.
    allow <<methods>> : if <<condition>>
  }
}

من المهم فهم المفاهيم الأساسية التالية أثناء إنشاء القواعد:

  • الطلب: الطريقة أو الأساليب التي تم استدعاؤها في بيان allow . هذه هي الأساليب التي تسمح بتشغيلها. الطرق القياسية هي: get list create update delete . تتيح أساليب read write الملائمة وصولاً واسع النطاق للقراءة والكتابة على قاعدة البيانات المحددة أو مسار التخزين.
  • المسار: قاعدة البيانات أو موقع التخزين، الذي يتم تمثيله كمسار URI.
  • القاعدة: عبارة allow ، التي تتضمن شرطًا يسمح بالطلب إذا تم تقييمه على أنه صحيح.

يتم وصف كل من هذه المفاهيم بمزيد من التفصيل أدناه.

سحابة التخزين

تستخدم قواعد أمان Firebase في Cloud Firestore وCloud Storage البنية والتركيب التاليين:

service <<name>> {
  // Match the resource path.
  match <<path>> {
    // Allow the request if the following conditions are true.
    allow <<methods>> : if <<condition>>
  }
}

من المهم فهم المفاهيم الأساسية التالية أثناء إنشاء القواعد:

  • الطلب: الطريقة أو الأساليب التي تم استدعاؤها في بيان allow . هذه هي الأساليب التي تسمح بتشغيلها. الطرق القياسية هي: get list create update delete . تتيح أساليب read write الملائمة وصولاً واسع النطاق للقراءة والكتابة على قاعدة البيانات المحددة أو مسار التخزين.
  • المسار: قاعدة البيانات أو موقع التخزين، الذي يتم تمثيله كمسار URI.
  • القاعدة: عبارة allow ، التي تتضمن شرطًا يسمح بالطلب إذا تم تقييمه على أنه صحيح.

يتم وصف كل من هذه المفاهيم بمزيد من التفصيل أدناه.

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

في قاعدة بيانات Realtime، تتكون قواعد أمان Firebase من تعبيرات تشبه JavaScript موجودة في مستند JSON.

يستخدمون بناء الجملة التالي:

{
  "rules": {
    "<<path>>": {
    // Allow the request if the condition for each method is true.
      ".read": <<condition>>,
      ".write": <<condition>>,
      ".validate": <<condition>>
    }
  }
}

هناك ثلاثة عناصر أساسية في القاعدة:

  • المسار: موقع قاعدة البيانات. وهذا يعكس بنية JSON الخاصة بقاعدة بياناتك.
  • الطلب: هذه هي الطرق التي تستخدمها القاعدة لمنح حق الوصول. تمنح قواعد read write وصولاً واسع النطاق للقراءة والكتابة، بينما تعمل قواعد validate كتحقق ثانوي لمنح الوصول استنادًا إلى البيانات الواردة أو الموجودة.
  • الشرط: الشرط الذي يسمح بالطلب إذا تم تقييمه على أنه صحيح.

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

سحابة فايرستور

العناصر الأساسية للقاعدة في Cloud Firestore وCloud Storage هي كما يلي:

  • إعلان service : يعلن عن منتج Firebase الذي تنطبق عليه القواعد.
  • كتلة match : تحدد مسارًا في قاعدة البيانات أو مجموعة التخزين التي تنطبق عليها القواعد.
  • بيان allow : يوفر شروط منح الوصول، متباينة حسب الطرق. تتضمن الطرق المدعومة: get ، list ، create ، update ، delete ، والطرق الملائمة read write .
  • إعلانات function الاختيارية: توفير القدرة على دمج الشروط والتفافها للاستخدام عبر قواعد متعددة.

تحتوي service على كتلة match واحدة أو أكثر مع عبارات allow التي توفر شروط منح الوصول إلى الطلبات. تتوفر متغيرات request resource للاستخدام في شروط القاعدة. تدعم لغة قواعد أمان Firebase أيضًا إعلانات function .

نسخة بناء الجملة

يشير بيان syntax إلى إصدار لغة قواعد Firebase المستخدمة لكتابة المصدر. أحدث إصدار من اللغة هو v2 .

rules_version = '2';
service cloud.firestore {
...
}

إذا لم يتم توفير عبارة rules_version ، فسيتم تقييم القواعد الخاصة بك باستخدام محرك v1 .

خدمة

يحدد إعلان service منتج Firebase أو الخدمة التي تنطبق عليها قواعدك. يمكنك تضمين إعلان service واحد فقط لكل ملف مصدر.

سحابة فايرستور
service cloud.firestore {
 // Your 'match' blocks with their corresponding 'allow' statements and
 // optional 'function' declarations are contained here
}
سحابة التخزين
service firebase.storage {
  // Your 'match' blocks with their corresponding 'allow' statements and
  // optional 'function' declarations are contained here
}

إذا كنت تحدد قواعد لكل من Cloud Firestore وCloud Storage باستخدام Firebase CLI، فسيتعين عليك الاحتفاظ بها في ملفات منفصلة.

مباراة

تعلن كتلة match عن نمط path مطابق لمسار العملية المطلوبة ( request.path الوارد). يجب أن يحتوي نص match على كتلة match متداخلة واحدة أو أكثر، أو عبارات allow ، أو إعلانات function . المسار في كتل match المتداخلة مرتبط بالمسار الموجود في كتلة match الأصلية.

نمط path هو اسم يشبه الدليل وقد يتضمن متغيرات أو أحرف بدل. يسمح نمط path بمطابقات المقاطع ذات المسار الواحد والمسارات المتعددة. تكون أي متغيرات مرتبطة path مرئية ضمن نطاق match أو أي نطاق متداخل حيث يتم الإعلان عن path .

قد تكون التطابقات مع نمط path جزئية أو كاملة:

  • التطابقات الجزئية: نمط path عبارة عن بادئة مطابقة لـ request.path .
  • التطابقات الكاملة: يتطابق نمط path مع request.path بأكمله.

عند إجراء تطابق كامل ، يتم تقييم القواعد داخل الكتلة. عند إجراء مطابقة جزئية ، يتم اختبار قواعد match المتداخلة لمعرفة ما إذا كان أي path متداخل سيكمل المطابقة.

يتم تقييم القواعد في كل match كامل لتحديد ما إذا كان سيتم السماح بالطلب أم لا. إذا كانت أي قاعدة مطابقة تمنح حق الوصول، فسيتم السماح بالطلب. إذا لم تمنح أي قاعدة مطابقة حق الوصول، فسيتم رفض الطلب.

// Given request.path == /example/hello/nested/path the following
// declarations indicate whether they are a partial or complete match and
// the value of any variables visible within the scope.
service firebase.storage {
  // Partial match.
  match /example/{singleSegment} {   // `singleSegment` == 'hello'
    allow write;                     // Write rule not evaluated.
    // Complete match.
    match /nested/path {             // `singleSegment` visible in scope.
      allow read;                    // Read rule is evaluated.
    }
  }
  // Complete match.
  match /example/{multiSegment=**} { // `multiSegment` == /hello/nested/path
    allow read;                      // Read rule is evaluated.
  }
}

كما يوضح المثال أعلاه، تدعم إعلانات path المتغيرات التالية:

  • حرف بدل أحادي المقطع: يتم الإعلان عن متغير حرف بدل في المسار عن طريق تغليف متغير بين قوسين متعرجين: {variable} . يمكن الوصول إلى هذا المتغير ضمن عبارة match string .
  • حرف البدل العودي: يطابق حرف البدل العودي أو متعدد المقاطع مقاطع مسار متعددة عند المسار أو أسفله. يتطابق حرف البدل هذا مع جميع المسارات الموجودة أسفل الموقع الذي قمت بتعيينه عليه. يمكنك الإعلان عن ذلك عن طريق إضافة السلسلة =** في نهاية متغير المقطع الخاص بك: {variable=**} . يمكن الوصول إلى هذا المتغير ضمن عبارة match ككائن path .
يسمح

تحتوي كتلة match على واحد أو أكثر من عبارات allow . هذه هي القواعد الفعلية الخاصة بك. يمكنك تطبيق قواعد allow على طريقة واحدة أو أكثر. يجب أن يتم تقييم الشروط الموجودة في بيان allow على أنها صحيحة بالنسبة لـ Cloud Firestore أو Cloud Storage لمنح أي طلب وارد. يمكنك أيضًا كتابة عبارات allow بدون شروط، على سبيل المثال، allow read . إذا لم تتضمن عبارة allow شرطًا، فإنها تسمح دائمًا بطلب هذه الطريقة.

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

خذ بعين الاعتبار المثال التالي، حيث يمكن لأي مستخدم قراءة أو حذف أي من ملفاته الخاصة. تسمح القاعدة الأكثر دقة بالكتابة فقط إذا كان المستخدم الذي يطلب الكتابة يمتلك الملف وكان الملف بتنسيق PNG. يمكن للمستخدم حذف أي ملفات في المسار الفرعي — حتى لو لم تكن ملفات PNG — لأن القاعدة السابقة تسمح بذلك.

service firebase.storage {
  // Allow the requestor to read or delete any resource on a path under the
  // user directory.
  match /users/{userId}/{anyUserFile=**} {
    allow read, delete: if request.auth != null && request.auth.uid == userId;
  }

  // Allow the requestor to create or update their own images.
  // When 'request.method' == 'delete' this rule and the one matching
  // any path under the user directory would both match and the `delete`
  // would be permitted.

  match /users/{userId}/images/{imageId} {
    // Whether to permit the request depends on the logical OR of all
    // matched rules. This means that even if this rule did not explicitly
    // allow the 'delete' the earlier rule would have.
    allow write: if request.auth != null && request.auth.uid == userId && imageId.matches('*.png');
  }
}
طريقة

يتضمن كل بيان allow طريقة تمنح الوصول للطلبات الواردة من نفس الطريقة.

طريقة نوع الطلب
أساليب الراحة
read أي نوع من طلب القراءة
write أي نوع من طلبات الكتابة
الطرق القياسية
get قراءة طلبات المستندات أو الملفات الفردية
list قراءة طلبات الاستعلامات والمجموعات
create كتابة مستندات أو ملفات جديدة
update الكتابة إلى مستندات قاعدة البيانات الموجودة أو تحديث البيانات التعريفية للملف
delete حذف البيانات

لا يمكنك تداخل أساليب القراءة في نفس كتلة match أو أساليب الكتابة المتعارضة في نفس إعلان path .

على سبيل المثال، قد تفشل القواعد التالية:

service bad.example {
  match /rules/with/overlapping/methods {
    // This rule allows reads to all authenticated users
    allow read: if request.auth != null;

    match another/subpath {
      // This secondary, more specific read rule causes an error
      allow get: if request.auth != null && request.auth.uid == "me";
      // Overlapping write methods in the same path cause an error as well
      allow write: if request.auth != null;
      allow create: if request.auth != null && request.auth.uid == "me";
    }
  }
}
وظيفة

عندما تصبح قواعد الأمان الخاصة بك أكثر تعقيدًا، قد ترغب في تضمين مجموعات من الشروط في الوظائف التي يمكنك إعادة استخدامها عبر مجموعة القواعد الخاصة بك. تدعم قواعد الأمان الوظائف المخصصة. يشبه بناء جملة الوظائف المخصصة جافا سكريبت إلى حد ما، لكن وظائف قواعد الأمان مكتوبة بلغة خاصة بالمجال ولها بعض القيود المهمة:

  • يمكن أن تحتوي الوظائف على عبارة return واحدة فقط. ولا يمكن أن تحتوي على أي منطق إضافي. على سبيل المثال، لا يمكنهم تنفيذ الحلقات أو الاتصال بخدمات خارجية.
  • يمكن للوظائف الوصول تلقائيًا إلى الوظائف والمتغيرات من النطاق الذي تم تعريفها فيه. على سبيل المثال، تتمتع الوظيفة المحددة ضمن نطاق service cloud.firestore بإمكانية الوصول إلى متغير resource والوظائف المضمنة مثل get() و exists() .
  • قد تستدعي الوظائف وظائف أخرى ولكن لا يجوز تكرارها. يقتصر إجمالي عمق مكدس الاستدعاءات على 20.
  • في إصدار القواعد v2 ، يمكن للوظائف تعريف المتغيرات باستخدام الكلمة الأساسية let . يمكن أن تحتوي الوظائف على ما يصل إلى 10 روابط Let، لكن يجب أن تنتهي ببيان return.

يتم تعريف الدالة باستخدام الكلمة الأساسية function ولا تأخذ أي وسيطات أو أكثر. على سبيل المثال، قد ترغب في دمج نوعي الشروط المستخدمة في الأمثلة أعلاه في دالة واحدة:

service cloud.firestore {
  match /databases/{database}/documents {
    // True if the user is signed in or the requested data is 'public'
    function signedInOrPublic() {
      return request.auth.uid != null || resource.data.visibility == 'public';
    }

    match /cities/{city} {
      allow read, write: if signedInOrPublic();
    }

    match /users/{user} {
      allow read, write: if signedInOrPublic();
    }
  }
}

فيما يلي مثال يوضح وسيطات الوظائف والسماح بالمهام. دع بيانات المهمة يجب أن تكون مفصولة بفواصل منقوطة.

function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
  return isAuthor || isAdmin;
}

لاحظ كيف يفرض تعيين isAdmin بحثًا عن مجموعة المسؤولين. لإجراء تقييم بطيء دون الحاجة إلى عمليات بحث غير ضرورية، استفد من طبيعة الدائرة القصيرة لـ && (AND) و || (OR) لاستدعاء دالة ثانية فقط إذا تبين أن isAuthor صحيح (لمقارنات && ) أو خطأ (لمقارنات || ).

function isAdmin(userId) {
  return exists(/databases/$(database)/documents/admins/$(userId));
}
function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  // `||` is short-circuiting; isAdmin called only if isAuthor == false.
  return isAuthor || isAdmin(userId);
}

إن استخدام الوظائف في قواعد الأمان الخاصة بك يجعلها أكثر قابلية للصيانة مع تزايد تعقيد قواعدك.

سحابة التخزين

العناصر الأساسية للقاعدة في Cloud Firestore وCloud Storage هي كما يلي:

  • إعلان service : يعلن عن منتج Firebase الذي تنطبق عليه القواعد.
  • كتلة match : تحدد مسارًا في قاعدة البيانات أو مجموعة التخزين التي تنطبق عليها القواعد.
  • بيان allow : يوفر شروط منح الوصول، متباينة حسب الأساليب. تتضمن الطرق المدعومة: get ، list ، create ، update ، delete ، والطرق الملائمة read write .
  • إعلانات function الاختيارية: توفير القدرة على دمج الشروط والتفافها للاستخدام عبر قواعد متعددة.

تحتوي service على كتلة match واحدة أو أكثر مع عبارات allow التي توفر شروط منح الوصول إلى الطلبات. تتوفر متغيرات request resource للاستخدام في شروط القاعدة. تدعم لغة قواعد أمان Firebase أيضًا إعلانات function .

نسخة بناء الجملة

يشير بيان syntax إلى إصدار لغة قواعد Firebase المستخدمة لكتابة المصدر. أحدث إصدار من اللغة هو v2 .

rules_version = '2';
service cloud.firestore {
...
}

إذا لم يتم توفير عبارة rules_version ، فسيتم تقييم القواعد الخاصة بك باستخدام محرك v1 .

خدمة

يحدد إعلان service منتج Firebase أو الخدمة التي تنطبق عليها قواعدك. يمكنك تضمين إعلان service واحد فقط لكل ملف مصدر.

سحابة فايرستور
service cloud.firestore {
 // Your 'match' blocks with their corresponding 'allow' statements and
 // optional 'function' declarations are contained here
}
سحابة التخزين
service firebase.storage {
  // Your 'match' blocks with their corresponding 'allow' statements and
  // optional 'function' declarations are contained here
}

إذا كنت تحدد قواعد لكل من Cloud Firestore وCloud Storage باستخدام Firebase CLI، فسيتعين عليك الاحتفاظ بها في ملفات منفصلة.

مباراة

تعلن كتلة match عن نمط path مطابق لمسار العملية المطلوبة ( request.path الوارد). يجب أن يحتوي نص match على كتلة match متداخلة واحدة أو أكثر، أو عبارات allow ، أو إعلانات function . المسار في كتل match المتداخلة مرتبط بالمسار الموجود في كتلة match الأصلية.

نمط path هو اسم يشبه الدليل وقد يتضمن متغيرات أو أحرف بدل. يسمح نمط path بمطابقات المقاطع ذات المسار الواحد والمسارات المتعددة. تكون أي متغيرات مرتبطة path مرئية ضمن نطاق match أو أي نطاق متداخل حيث يتم الإعلان عن path .

قد تكون التطابقات مع نمط path جزئية أو كاملة:

  • التطابقات الجزئية: نمط path عبارة عن بادئة مطابقة لـ request.path .
  • التطابقات الكاملة: يتطابق نمط path مع request.path بأكمله.

عند إجراء تطابق كامل ، يتم تقييم القواعد داخل الكتلة. عند إجراء مطابقة جزئية ، يتم اختبار قواعد match المتداخلة لمعرفة ما إذا كان أي path متداخل سيكمل المطابقة.

يتم تقييم القواعد في كل match كامل لتحديد ما إذا كان سيتم السماح بالطلب أم لا. إذا كانت أي قاعدة مطابقة تمنح حق الوصول، فسيتم السماح بالطلب. إذا لم تمنح أي قاعدة مطابقة حق الوصول، فسيتم رفض الطلب.

// Given request.path == /example/hello/nested/path the following
// declarations indicate whether they are a partial or complete match and
// the value of any variables visible within the scope.
service firebase.storage {
  // Partial match.
  match /example/{singleSegment} {   // `singleSegment` == 'hello'
    allow write;                     // Write rule not evaluated.
    // Complete match.
    match /nested/path {             // `singleSegment` visible in scope.
      allow read;                    // Read rule is evaluated.
    }
  }
  // Complete match.
  match /example/{multiSegment=**} { // `multiSegment` == /hello/nested/path
    allow read;                      // Read rule is evaluated.
  }
}

كما يوضح المثال أعلاه، تدعم إعلانات path المتغيرات التالية:

  • حرف بدل أحادي المقطع: يتم الإعلان عن متغير حرف بدل في المسار عن طريق تغليف متغير بين قوسين متعرجين: {variable} . يمكن الوصول إلى هذا المتغير ضمن عبارة match string .
  • حرف البدل العودي: يطابق حرف البدل العودي أو متعدد المقاطع مقاطع مسار متعددة عند المسار أو أسفله. يتطابق حرف البدل هذا مع جميع المسارات الموجودة أسفل الموقع الذي قمت بتعيينه عليه. يمكنك الإعلان عن ذلك عن طريق إضافة السلسلة =** في نهاية متغير المقطع الخاص بك: {variable=**} . يمكن الوصول إلى هذا المتغير ضمن عبارة match ككائن path .
يسمح

تحتوي كتلة match على واحد أو أكثر من عبارات allow . هذه هي القواعد الفعلية الخاصة بك. يمكنك تطبيق قواعد allow على طريقة واحدة أو أكثر. يجب أن يتم تقييم الشروط الموجودة في بيان allow على أنها صحيحة بالنسبة لـ Cloud Firestore أو Cloud Storage لمنح أي طلب وارد. يمكنك أيضًا كتابة عبارات allow بدون شروط، على سبيل المثال، allow read . إذا لم تتضمن عبارة allow شرطًا، فإنها تسمح دائمًا بطلب هذه الطريقة.

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

خذ بعين الاعتبار المثال التالي، حيث يمكن لأي مستخدم قراءة أو حذف أي من ملفاته الخاصة. تسمح القاعدة الأكثر دقة بالكتابة فقط إذا كان المستخدم الذي يطلب الكتابة يمتلك الملف وكان الملف بتنسيق PNG. يمكن للمستخدم حذف أي ملفات في المسار الفرعي — حتى لو لم تكن ملفات PNG — لأن القاعدة السابقة تسمح بذلك.

service firebase.storage {
  // Allow the requestor to read or delete any resource on a path under the
  // user directory.
  match /users/{userId}/{anyUserFile=**} {
    allow read, delete: if request.auth != null && request.auth.uid == userId;
  }

  // Allow the requestor to create or update their own images.
  // When 'request.method' == 'delete' this rule and the one matching
  // any path under the user directory would both match and the `delete`
  // would be permitted.

  match /users/{userId}/images/{imageId} {
    // Whether to permit the request depends on the logical OR of all
    // matched rules. This means that even if this rule did not explicitly
    // allow the 'delete' the earlier rule would have.
    allow write: if request.auth != null && request.auth.uid == userId && imageId.matches('*.png');
  }
}
طريقة

يتضمن كل بيان allow طريقة تمنح الوصول للطلبات الواردة من نفس الطريقة.

طريقة نوع الطلب
أساليب الراحة
read أي نوع من طلب القراءة
write أي نوع من طلبات الكتابة
الطرق القياسية
get قراءة طلبات المستندات أو الملفات الفردية
list قراءة طلبات الاستعلامات والمجموعات
create كتابة مستندات أو ملفات جديدة
update الكتابة إلى مستندات قاعدة البيانات الموجودة أو تحديث البيانات التعريفية للملف
delete حذف البيانات

لا يمكنك تداخل أساليب القراءة في نفس كتلة match أو أساليب الكتابة المتعارضة في نفس إعلان path .

على سبيل المثال، قد تفشل القواعد التالية:

service bad.example {
  match /rules/with/overlapping/methods {
    // This rule allows reads to all authenticated users
    allow read: if request.auth != null;

    match another/subpath {
      // This secondary, more specific read rule causes an error
      allow get: if request.auth != null && request.auth.uid == "me";
      // Overlapping write methods in the same path cause an error as well
      allow write: if request.auth != null;
      allow create: if request.auth != null && request.auth.uid == "me";
    }
  }
}
وظيفة

عندما تصبح قواعد الأمان الخاصة بك أكثر تعقيدًا، قد ترغب في تضمين مجموعات من الشروط في الوظائف التي يمكنك إعادة استخدامها عبر مجموعة القواعد الخاصة بك. تدعم قواعد الأمان الوظائف المخصصة. يشبه بناء جملة الوظائف المخصصة جافا سكريبت إلى حد ما، لكن وظائف قواعد الأمان مكتوبة بلغة خاصة بالمجال ولها بعض القيود المهمة:

  • يمكن أن تحتوي الوظائف على عبارة return واحدة فقط. ولا يمكن أن تحتوي على أي منطق إضافي. على سبيل المثال، لا يمكنهم تنفيذ الحلقات أو الاتصال بخدمات خارجية.
  • يمكن للوظائف الوصول تلقائيًا إلى الوظائف والمتغيرات من النطاق الذي تم تعريفها فيه. على سبيل المثال، تتمتع الوظيفة المحددة ضمن نطاق service cloud.firestore بإمكانية الوصول إلى متغير resource والوظائف المضمنة مثل get() و exists() .
  • قد تستدعي الوظائف وظائف أخرى ولكن لا يجوز تكرارها. يقتصر إجمالي عمق مكدس الاستدعاءات على 20.
  • في إصدار القواعد v2 ، يمكن للوظائف تعريف المتغيرات باستخدام الكلمة الأساسية let . يمكن أن تحتوي الوظائف على ما يصل إلى 10 روابط Let، لكن يجب أن تنتهي ببيان return.

يتم تعريف الدالة باستخدام الكلمة الأساسية function ولا تأخذ أي وسيطات أو أكثر. على سبيل المثال، قد ترغب في دمج نوعي الشروط المستخدمة في الأمثلة أعلاه في دالة واحدة:

service cloud.firestore {
  match /databases/{database}/documents {
    // True if the user is signed in or the requested data is 'public'
    function signedInOrPublic() {
      return request.auth.uid != null || resource.data.visibility == 'public';
    }

    match /cities/{city} {
      allow read, write: if signedInOrPublic();
    }

    match /users/{user} {
      allow read, write: if signedInOrPublic();
    }
  }
}

فيما يلي مثال يوضح وسيطات الوظائف والسماح بالمهام. دع بيانات المهمة يجب أن تكون مفصولة بفواصل منقوطة.

function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
  return isAuthor || isAdmin;
}

لاحظ كيف يفرض تعيين isAdmin بحثًا عن مجموعة المسؤولين. لإجراء تقييم بطيء دون الحاجة إلى عمليات بحث غير ضرورية، استفد من طبيعة الدائرة القصيرة لـ && (AND) و || (OR) لاستدعاء دالة ثانية فقط إذا تبين أن isAuthor صحيح (لمقارنات && ) أو خطأ (لمقارنات || ).

function isAdmin(userId) {
  return exists(/databases/$(database)/documents/admins/$(userId));
}
function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  // `||` is short-circuiting; isAdmin called only if isAuthor == false.
  return isAuthor || isAdmin(userId);
}

إن استخدام الوظائف في قواعد الأمان الخاصة بك يجعلها أكثر قابلية للصيانة مع تزايد تعقيد قواعدك.

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

كما هو موضح أعلاه، تتضمن قواعد قاعدة البيانات في الوقت الفعلي ثلاثة عناصر أساسية: موقع قاعدة البيانات كمرآة لبنية JSON الخاصة بقاعدة البيانات، ونوع الطلب، وشرط منح الوصول.

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

يجب أن يتبع هيكل قواعدك هيكل البيانات التي قمت بتخزينها في قاعدة البيانات الخاصة بك. على سبيل المثال، في تطبيق الدردشة الذي يحتوي على قائمة رسائل، قد تكون لديك بيانات تبدو كما يلي:

  {
    "messages": {
      "message0": {
        "content": "Hello",
        "timestamp": 1405704370369
      },
      "message1": {
        "content": "Goodbye",
        "timestamp": 1405704395231
      },
      ...
    }
  }

يجب أن تعكس القواعد الخاصة بك هذا الهيكل. على سبيل المثال:

  {
    "rules": {
      "messages": {
        "$message": {
          // only messages from the last ten minutes can be read
          ".read": "data.child('timestamp').val() > (now - 600000)",

          // new messages must have a string content and a number timestamp
          ".validate": "newData.hasChildren(['content', 'timestamp']) &&
                        newData.child('content').isString() &&
                        newData.child('timestamp').isNumber()"
        }
      }
    }
  }

كما يوضح المثال أعلاه، تدعم قواعد قاعدة بيانات الوقت الفعلي متغير $location لمطابقة مقاطع المسار. استخدم البادئة $ أمام مقطع المسار الخاص بك لمطابقة القاعدة الخاصة بك مع أي عقد فرعية على طول المسار.

  {
    "rules": {
      "rooms": {
        // This rule applies to any child of /rooms/, the key for each room id
        // is stored inside $room_id variable for reference
        "$room_id": {
          "topic": {
            // The room's topic can be changed if the room id has "public" in it
            ".write": "$room_id.contains('public')"
          }
        }
      }
    }
  }

يمكنك أيضًا استخدام $variable بالتوازي مع أسماء المسارات الثابتة.

  {
    "rules": {
      "widget": {
        // a widget can have a title or color attribute
        "title": { ".validate": true },
        "color": { ".validate": true },

        // but no other child paths are allowed
        // in this case, $other means any key excluding "title" and "color"
        "$other": { ".validate": false }
      }
    }
  }
طريقة

في قاعدة بيانات الوقت الحقيقي، هناك ثلاثة أنواع من القواعد. ينطبق اثنان من أنواع القواعد هذه - read write - على طريقة الطلب الوارد. يفرض نوع قاعدة validate هياكل البيانات ويتحقق من صحة تنسيق البيانات ومحتواها. تعمل القواعد على قواعد .validate القواعد بعد التحقق من أن قاعدة .write تمنح حق الوصول.

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

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

ظروف البناء

سحابة فايرستور

الشرط هو تعبير منطقي يحدد ما إذا كان يجب السماح بعملية معينة أم رفضها. توفر متغيرات request resource السياق لهذه الشروط.

متغير request

يتضمن متغير request الحقول التالية والمعلومات المقابلة:

request.auth

رمز ويب JSON (JWT) يحتوي على بيانات اعتماد المصادقة من مصادقة Firebase. يحتوي رمز auth على مجموعة من المطالبات القياسية وأي مطالبات مخصصة تقوم بإنشائها من خلال مصادقة Firebase. تعرف على المزيد حول قواعد أمان Firebase والمصادقة .

request.method

قد يكون request.method أيًا من الطرق القياسية أو طريقة مخصصة. توجد أيضًا طرق read write الملائمة لتبسيط قواعد الكتابة التي تنطبق على جميع الطرق القياسية للقراءة فقط أو جميع الطرق القياسية للكتابة فقط على التوالي.

request.params

يتضمن request.params أي بيانات لا تتعلق تحديدًا بـ request.resource والتي قد تكون مفيدة للتقييم. من الناحية العملية، يجب أن تكون هذه الخريطة فارغة لجميع الطرق القياسية، ويجب أن تحتوي على بيانات غير موارد للطرق المخصصة. يجب أن تحرص الخدمات على عدم إعادة تسمية أو تعديل نوع أي من المفاتيح والقيم المقدمة كمعلمات.

request.path

request.path هو المسار resource الهدف. المسار متعلق بالخدمة. يتم ترميز مقاطع المسار التي تحتوي على أحرف غير آمنة لعنوان URL مثل / بعنوان URL.

متغير resource

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

المشغلين وأسبقية المشغل

استخدم الجدول أدناه كمرجع للمشغلين والأسبقية المقابلة لهم في قواعد Cloud Firestore وCloud Storage.

نظرا للتعبيرات التعسفية a و b ، والحقل f ، والفهرس i .

المشغل أو العامل وصف الترابط
a[i] a() af الفهرس، الاتصال، الوصول الميداني من اليسار إلى اليمين
!a -a النفي الأحادي من اليمين الى اليسار
a/ba%ba*b عوامل الضرب من اليسار إلى اليمين
a+b ab مشغلي المضافة من اليسار إلى اليمين
a>ba>=ba العوامل العلاقية من اليسار إلى اليمين
a in b التواجد في القائمة أو الخريطة من اليسار إلى اليمين
a is type مقارنة النوع، حيث يمكن أن يكون type bool أو int أو float أو number أو string أو list أو Map أو timestamp أو term أو path أو latlng من اليسار إلى اليمين
a==ba!=b عوامل المقارنة من اليسار إلى اليمين
a && b مشروط و من اليسار إلى اليمين
a || b مشروط أو من اليسار إلى اليمين
a ? true_value : false_value التعبير الثلاثي من اليسار إلى اليمين

سحابة التخزين

الشرط هو تعبير منطقي يحدد ما إذا كان يجب السماح بعملية معينة أم رفضها. توفر متغيرات request resource السياق لهذه الشروط.

متغير request

يتضمن متغير request الحقول التالية والمعلومات المقابلة:

request.auth

رمز ويب JSON (JWT) يحتوي على بيانات اعتماد المصادقة من مصادقة Firebase. يحتوي رمز auth على مجموعة من المطالبات القياسية وأي مطالبات مخصصة تقوم بإنشائها من خلال مصادقة Firebase. تعرف على المزيد حول قواعد أمان Firebase والمصادقة .

request.method

قد يكون request.method أيًا من الطرق القياسية أو طريقة مخصصة. توجد أيضًا طرق read write الملائمة لتبسيط قواعد الكتابة التي تنطبق على جميع الطرق القياسية للقراءة فقط أو جميع الطرق القياسية للكتابة فقط على التوالي.

request.params

يتضمن request.params أي بيانات لا تتعلق تحديدًا بـ request.resource والتي قد تكون مفيدة للتقييم. من الناحية العملية، يجب أن تكون هذه الخريطة فارغة لجميع الطرق القياسية، ويجب أن تحتوي على بيانات غير موارد للطرق المخصصة. يجب أن تحرص الخدمات على عدم إعادة تسمية أو تعديل نوع أي من المفاتيح والقيم المقدمة كمعلمات.

request.path

request.path هو المسار resource الهدف. المسار متعلق بالخدمة. يتم ترميز مقاطع المسار التي تحتوي على أحرف غير آمنة لعنوان URL مثل / بعنوان URL.

متغير resource

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

المشغلين وأسبقية المشغل

استخدم الجدول أدناه كمرجع للمشغلين والأسبقية المقابلة لهم في قواعد Cloud Firestore وCloud Storage.

نظرا للتعبيرات التعسفية a و b ، والحقل f ، والفهرس i .

المشغل أو العامل وصف الترابط
a[i] a() af الفهرس، الاتصال، الوصول الميداني من اليسار إلى اليمين
!a -a النفي الأحادي من اليمين الى اليسار
a/ba%ba*b عوامل الضرب من اليسار إلى اليمين
a+b ab مشغلي المضافة من اليسار إلى اليمين
a>ba>=ba العوامل العلاقية من اليسار إلى اليمين
a in b التواجد في القائمة أو الخريطة من اليسار إلى اليمين
a is type مقارنة النوع، حيث يمكن أن يكون type bool أو int أو float أو number أو string أو list أو Map أو timestamp أو term أو path أو latlng من اليسار إلى اليمين
a==ba!=b عوامل المقارنة من اليسار إلى اليمين
a && b مشروط و من اليسار إلى اليمين
a || b مشروط أو من اليسار إلى اليمين
a ? true_value : false_value التعبير الثلاثي من اليسار إلى اليمين

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

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

المتغيرات المحددة مسبقا

هناك عدد من المتغيرات المفيدة المحددة مسبقًا والتي يمكن الوصول إليها داخل تعريف القاعدة. وفيما يلي نبذة مختصرة عن كل منها:

المتغيرات المحددة مسبقا
الآن الوقت الحالي بالمللي ثانية منذ عصر Linux. يعمل هذا بشكل جيد بشكل خاص للتحقق من صحة الطوابع الزمنية التي تم إنشاؤها باستخدام firebase.database.ServerValue.TIMESTAMP الخاص بـ SDK.
جذر RuleDataSnapshot يمثل المسار الجذر في قاعدة بيانات Firebase كما كان موجودًا قبل محاولة العملية.
بيانات جديدة RuleDataSnapshot الذي يمثل البيانات بالشكل الذي ستكون عليه بعد محاولة العملية. ويشمل البيانات الجديدة التي يتم كتابتها والبيانات الموجودة.
بيانات RuleDataSnapshot يمثل البيانات كما كانت موجودة قبل محاولة العملية.
المتغيرات $ مسار بدل يستخدم لتمثيل المعرفات والمفاتيح الفرعية الديناميكية.
مصادقة يمثل حمولة الرمز المميز للمستخدم المصادق عليه.

يمكن استخدام هذه المتغيرات في أي مكان في القواعد الخاصة بك. على سبيل المثال، تضمن قواعد الأمان أدناه أن البيانات المكتوبة إلى العقدة /foo/ يجب أن تكون سلسلة أقل من 100 حرف:

{
  "rules": {
    "foo": {
      // /foo is readable by the world
      ".read": true,

      // /foo is writable by the world
      ".write": true,

      // data written to /foo must be a string less than 100 characters
      ".validate": "newData.isString() && newData.val().length < 100"
    }
  }
}
القواعد المبنية على البيانات

يمكن استخدام أي بيانات في قاعدة البيانات الخاصة بك في القواعد الخاصة بك. باستخدام المتغيرات المحددة مسبقًا root و data و newData ، يمكنك الوصول إلى أي مسار كما لو كان موجودًا قبل أو بعد حدث الكتابة.

خذ بعين الاعتبار هذا المثال، الذي يسمح بعمليات الكتابة طالما أن قيمة العقدة /allow_writes/ true ، ولا تحتوي العقدة الأصلية على مجموعة علامات readOnly ، ويوجد طفل اسمه foo في البيانات المكتوبة حديثًا:

".write": "root.child('allow_writes').val() === true &&
          !data.parent().child('readOnly').exists() &&
          newData.child('foo').exists()"
القواعد المبنية على الاستعلام

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

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

"baskets": {
  ".read": "auth.uid !== null &&
            query.orderByChild === 'owner' &&
            query.equalTo === auth.uid" // restrict basket access to owner of basket
}

قد ينجح الاستعلام التالي، الذي يتضمن معلمات الاستعلام في القاعدة:

db.ref("baskets").orderByChild("owner")
                 .equalTo(auth.currentUser.uid)
                 .on("value", cb)                 // Would succeed

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

db.ref("baskets").on("value", cb)                 // Would fail with PermissionDenied

يمكنك أيضًا استخدام القواعد المستندة إلى الاستعلام للحد من كمية البيانات التي يقوم العميل بتنزيلها من خلال عمليات القراءة.

على سبيل المثال، تحدد القاعدة التالية إمكانية الوصول للقراءة فقط إلى أول 1000 نتيجة للاستعلام، حسب الترتيب حسب الأولوية:

messages: {
  ".read": "query.orderByKey &&
            query.limitToFirst <= 1000"
}

// Example queries:

db.ref("messages").on("value", cb)                // Would fail with PermissionDenied

db.ref("messages").limitToFirst(1000)
                  .on("value", cb)                // Would succeed (default order by key)

query. تتوفر التعبيرات في قواعد أمان قاعدة البيانات في الوقت الحقيقي.

تعبيرات القاعدة المستندة إلى الاستعلام
تعبير يكتب وصف
query.orderByKey
query.orderByPriority
query.orderByValue
منطقية صحيح بالنسبة للاستعلامات المرتبة حسب المفتاح أو الأولوية أو القيمة. باطل غير ذلك.
query.orderByChild خيط
باطل
استخدم سلسلة لتمثيل المسار النسبي للعقدة الفرعية. على سبيل المثال، query.orderByChild === "address/zip" . إذا لم يتم ترتيب الاستعلام بواسطة عقدة فرعية، فستكون هذه القيمة فارغة.
query.startAt
query.endAt
query.equalTo
خيط
رقم
منطقية
باطل
استرداد حدود الاستعلام المنفذ، أو إرجاع قيمة فارغة إذا لم تكن هناك مجموعة مرتبطة.
query.limitToFirst
query.limitToLast
رقم
باطل
استرداد الحد الأقصى للاستعلام المنفذ، أو إرجاع قيمة فارغة إذا لم يتم تعيين حد.
العاملين

تدعم قواعد قاعدة بيانات الوقت الفعلي عددًا من عوامل التشغيل التي يمكنك استخدامها لدمج المتغيرات في بيان الشرط. راجع القائمة الكاملة للمشغلين في الوثائق المرجعية .

خلق الظروف

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

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