تستفيد قواعد أمان 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 و 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 منطقيًا ، أو 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 و 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 منطقيًا ، أو 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.
تتوفر التعبيرات في قواعد أمان قاعدة البيانات Realtime.
تعبيرات القواعد المستندة إلى الاستعلام | ||
---|---|---|
تعبير | يكتب | وصف |
الاستعلام. OrderByKey الاستعلام. ترتيب حسب الأولوية الاستعلام. OrderByValue | قيمة منطقية | صواب للاستعلامات المرتبة حسب المفتاح أو الأولوية أو القيمة. خطأ خلاف ذلك. |
الاستعلام. OrderByChild | خيط باطل | استخدم سلسلة لتمثيل المسار النسبي لعقدة فرعية. على سبيل المثال ، query.orderByChild === "address/zip" . إذا لم يتم ترتيب الاستعلام بواسطة عقدة فرعية ، فستكون هذه القيمة خالية. |
query.startAt query.endAt query.equalTo | خيط رقم قيمة منطقية باطل | يسترجع حدود الاستعلام المنفذ ، أو يعيد قيمة فارغة إذا لم تكن هناك مجموعة محددة. |
query.limitToFirst الاستعلام.حد إلى آخر | رقم باطل | يسترجع الحد الأقصى للاستعلام المنفذ ، أو يعيد القيمة فارغة إذا لم يكن هناك حد معين. |
العاملين
تدعم قواعد قاعدة البيانات في الوقت الفعلي عددًا من العوامل التي يمكنك استخدامها لدمج المتغيرات في بيان الشرط. انظر القائمة الكاملة للمشغلين في الوثائق المرجعية .
خلق الظروف
ستختلف ظروفك الفعلية بناءً على حق الوصول الذي تريد منحه. توفر القواعد عن قصد درجة هائلة من المرونة ، لذلك يمكن أن تكون قواعد تطبيقك في النهاية بسيطة أو معقدة بالقدر الذي تريده.
للحصول على بعض الإرشادات حول إنشاء قواعد بسيطة وجاهزة للإنتاج ، راجع قواعد الأمان الأساسية .