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