Catch up on everything announced at Firebase Summit, and learn how Firebase can help you accelerate app development and run your app with confidence. Learn More

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

تنظيم صفحاتك في مجموعات يمكنك حفظ المحتوى وتصنيفه حسب إعداداتك المفضّلة.

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

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

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

تركيب اساسي

سحابة Firestore

تستخدم قواعد أمان 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 من تعبيرات شبيهة بجافا سكريبت مضمنة في مستند JSON.

يستخدمون الصيغة التالية:

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

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

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

حكم يبني

سحابة Firestore

العناصر الأساسية لقاعدة في 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 واحد لكل ملف مصدر.

سحابة Firestore

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";
    }
  }
}

دور

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

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

يتم تعريف 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) و || (أو) المقارنات لاستدعاء دالة ثانية فقط إذا تبين أن 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 واحد لكل ملف مصدر.

سحابة Firestore

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";
    }
  }
}

دور

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

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

يتم تعريف 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) و || (أو) المقارنات لاستدعاء دالة ثانية فقط إذا تبين أن 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);
}

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

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

كما هو موضح أعلاه ، تتضمن Realtime Database Rules ثلاثة عناصر أساسية: موقع قاعدة البيانات كنسخة مرآة لهيكل 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 }
      }
    }
  }

طريقة

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

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

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

شروط البناء

سحابة Firestore

الشرط هو تعبير منطقي يحدد ما إذا كان يجب السماح بعملية معينة أو رفضها. يوفر متغيرات 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 والتخزين السحابي.

بالنظر إلى التعبيرات التعسفية 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 منطقيًا ، أو int ، أو عائمًا ، أو رقمًا ، أو سلسلة ، أو قائمة ، أو خريطة ، أو طابعًا زمنيًا ، أو مدة ، أو مسارًا ، أو خط طول خط الطول من اليسار إلى اليمين
a==ba!=b عوامل المقارنة من اليسار إلى اليمين
a && b AND الشرطي من اليسار إلى اليمين
a || b OR الشرطي من اليسار إلى اليمين
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 والتخزين السحابي.

بالنظر إلى التعبيرات التعسفية 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 منطقيًا ، أو int ، أو عائمًا ، أو رقمًا ، أو سلسلة ، أو قائمة ، أو خريطة ، أو طابعًا زمنيًا ، أو مدة ، أو مسارًا ، أو خط طول خط الطول من اليسار إلى اليمين
a==ba!=b عوامل المقارنة من اليسار إلى اليمين
a && b AND الشرطي من اليسار إلى اليمين
a || b OR الشرطي من اليسار إلى اليمين
a ? true_value : false_value التعبير الثلاثي من اليسار إلى اليمين

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

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

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

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

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

يمكن استخدام هذه المتغيرات في أي مكان في القواعد الخاصة بك. على سبيل المثال ، تضمن قواعد الأمان أدناه أن البيانات المكتوبة في /foo/ node يجب أن تكون سلسلة أقل من 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. تتوفر التعبيرات في قواعد قاعدة البيانات في الوقت الفعلي.

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

العاملين

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

خلق الظروف

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

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