يمكنك استخدام قواعد أمان Firebase لكتابة بيانات جديدة بشكل مشروط استنادًا إلى البيانات الموجودة في قاعدة البيانات أو حاوية التخزين. يمكنك أيضًا كتابة القواعد التي تفرض عمليات التحقق من صحة البيانات عن طريق تقييد عمليات الكتابة بناءً على البيانات الجديدة التي يتم كتابتها. تابع القراءة لمعرفة المزيد حول القواعد التي تستخدم البيانات الموجودة لإنشاء شروط الأمان.
حدد منتجًا في كل قسم لمعرفة المزيد حول قواعد التحقق من صحة البيانات.
قيود على البيانات الجديدة
سحابة Firestore
إذا كنت تريد التأكد من عدم إنشاء مستند يحتوي على حقل معين ، يمكنك تضمين الحقل في شرط allow
. على سبيل المثال ، إذا كنت تريد رفض إنشاء أي مستندات تحتوي على حقل ranking
، فلن تسمح بذلك في شرط create
.
service cloud.firestore {
match /databases/{database}/documents {
// Disallow
match /cities/{city} {
allow create: if !("ranking" in request.resource.data)
}
}
}
قاعدة بيانات الوقت الفعلي
إذا كنت تريد التأكد من عدم إضافة البيانات التي تحتوي على قيم معينة إلى قاعدة البيانات الخاصة بك ، فيمكنك تضمين هذه القيمة في القواعد الخاصة بك وعدم السماح لها بالكتابة. على سبيل المثال ، إذا كنت تريد رفض أي كتابات تحتوي على قيم ranking
، فلن تسمح بالكتابة لأي مستندات ذات قيم ranking
.
{
"rules": {
// Write is allowed for all paths
".write": true,
// Allows writes only if new data doesn't include a `ranking` child value
".validate": "!newData.hasChild('ranking')
}
}
سحابة التخزين
إذا كنت تريد التأكد من عدم إنشاء ملف يحتوي على بيانات وصفية معينة ، يمكنك تضمين البيانات الأولية في شرط allow
. على سبيل المثال ، إذا كنت تريد رفض إنشاء أي ملفات تحتوي على بيانات ranking
، فلن تسمح بذلك في شرط create
.
service firebase.storage {
match /b/{bucket}/o {
match /files/{allFiles=**} {
// Disallow
allow create: if !("ranking" in request.resource.metadata)
}
}
}
استخدم البيانات الموجودة في قواعد أمان Firebase
سحابة Firestore
تخزن العديد من التطبيقات معلومات التحكم في الوصول كحقول في المستندات في قاعدة البيانات. يمكن لقواعد أمان Cloud Firestore السماح بالوصول أو رفضه ديناميكيًا استنادًا إلى بيانات المستند:
service cloud.firestore {
match /databases/{database}/documents {
// Allow the user to read data if the document has the 'visibility'
// field set to 'public'
match /cities/{city} {
allow read: if resource.data.visibility == 'public';
}
}
}
يشير متغير resource
إلى المستند المطلوب ، بينما resource.data
عبارة عن خريطة لجميع الحقول والقيم المخزنة في المستند. لمزيد من المعلومات حول متغير resource
، راجع الوثائق المرجعية .
عند كتابة البيانات ، قد ترغب في مقارنة البيانات الواردة بالبيانات الموجودة. يتيح لك ذلك القيام بأشياء مثل التأكد من عدم تغيير أحد الحقول ، أو أن الحقل قد زاد بمقدار واحد فقط ، أو أن القيمة الجديدة ستكون أسبوعًا على الأقل في المستقبل. في هذه الحالة ، إذا كانت مجموعة القواعد الخاصة بك تسمح بالكتابة المعلقة ، فإن متغير request.resource
يحتوي على الحالة المستقبلية للمستند. لعمليات update
التي تقوم فقط بتعديل مجموعة فرعية من حقول المستند ، سيحتوي متغير request.resource
على حالة المستند المعلقة بعد العملية. يمكنك التحقق من قيم الحقل في request.resource
لمنع تحديثات البيانات غير المرغوب فيها أو غير المتسقة:
service cloud.firestore {
match /databases/{database}/documents {
// Make sure all cities have a positive population and
// the name is not changed
match /cities/{city} {
allow update: if request.resource.data.population > 0
&& request.resource.data.name == resource.data.name;
}
}
}
قاعدة بيانات الوقت الفعلي
في Realtime Database ، استخدم قواعد .validate
لفرض هياكل البيانات والتحقق من صحة تنسيق البيانات ومحتواها. تقوم القواعد بتشغيل .validate
التحقق من صحة القواعد بعد التحقق من أن قاعدة .write
تمنح الوصول.
لا تتالي قواعد .validate
الصحة. إذا فشلت أي قاعدة تحقق من الصحة على أي مسار أو مسار فرعي في القاعدة ، فسيتم رفض عملية الكتابة بأكملها. بالإضافة إلى ذلك ، فإن تعريفات التحقق من الصحة تتحقق فقط من القيم غير الفارغة ، وتتجاهل بالتالي أي طلبات تحذف البيانات.
ضع في اعتبارك قواعد .validate
التالية:
{
"rules": {
// write is allowed for all paths
".write": true,
"widget": {
// a valid widget must have attributes "color" and "size"
// allows deleting widgets (since .validate is not applied to delete rules)
".validate": "newData.hasChildren(['color', 'size'])",
"size": {
// the value of "size" must be a number between 0 and 99
".validate": "newData.isNumber() &&
newData.val() >= 0 &&
newData.val() <= 99"
},
"color": {
// the value of "color" must exist as a key in our mythical
// /valid_colors/ index
".validate": "root.child('valid_colors/' + newData.val()).exists()"
}
}
}
}
ستؤدي طلبات الكتابة إلى قاعدة بيانات بالقواعد المذكورة أعلاه إلى النتائج التالية:
جافا سكريبت
var ref = db.ref("/widget"); // PERMISSION_DENIED: does not have children color and size ref.set('foo'); // PERMISSION DENIED: does not have child color ref.set({size: 22}); // PERMISSION_DENIED: size is not a number ref.set({ size: 'foo', color: 'red' }); // SUCCESS (assuming 'blue' appears in our colors list) ref.set({ size: 21, color: 'blue'}); // If the record already exists and has a color, this will // succeed, otherwise it will fail since newData.hasChildren(['color', 'size']) // will fail to validate ref.child('size').set(99);
ج موضوعية
FIRDatabaseReference *ref = [[[FIRDatabase database] reference] child: @"widget"]; // PERMISSION_DENIED: does not have children color and size [ref setValue: @"foo"]; // PERMISSION DENIED: does not have child color [ref setValue: @{ @"size": @"foo" }]; // PERMISSION_DENIED: size is not a number [ref setValue: @{ @"size": @"foo", @"color": @"red" }]; // SUCCESS (assuming 'blue' appears in our colors list) [ref setValue: @{ @"size": @21, @"color": @"blue" }]; // If the record already exists and has a color, this will // succeed, otherwise it will fail since newData.hasChildren(['color', 'size']) // will fail to validate [[ref child:@"size"] setValue: @99];
سويفت
var ref = FIRDatabase.database().reference().child("widget") // PERMISSION_DENIED: does not have children color and size ref.setValue("foo") // PERMISSION DENIED: does not have child color ref.setValue(["size": "foo"]) // PERMISSION_DENIED: size is not a number ref.setValue(["size": "foo", "color": "red"]) // SUCCESS (assuming 'blue' appears in our colors list) ref.setValue(["size": 21, "color": "blue"]) // If the record already exists and has a color, this will // succeed, otherwise it will fail since newData.hasChildren(['color', 'size']) // will fail to validate ref.child("size").setValue(99);
جافا
FirebaseDatabase database = FirebaseDatabase.getInstance(); DatabaseReference ref = database.getReference("widget"); // PERMISSION_DENIED: does not have children color and size ref.setValue("foo"); // PERMISSION DENIED: does not have child color ref.child("size").setValue(22); // PERMISSION_DENIED: size is not a number Map<String,Object> map = new HashMap<String, Object>(); map.put("size","foo"); map.put("color","red"); ref.setValue(map); // SUCCESS (assuming 'blue' appears in our colors list) map = new HashMap<String, Object>(); map.put("size", 21); map.put("color","blue"); ref.setValue(map); // If the record already exists and has a color, this will // succeed, otherwise it will fail since newData.hasChildren(['color', 'size']) // will fail to validate ref.child("size").setValue(99);
استراحة
# PERMISSION_DENIED: does not have children color and size curl -X PUT -d 'foo' \ https://docs-examples.firebaseio.com/rest/securing-data/example.json # PERMISSION DENIED: does not have child color curl -X PUT -d '{"size": 22}' \ https://docs-examples.firebaseio.com/rest/securing-data/example.json # PERMISSION_DENIED: size is not a number curl -X PUT -d '{"size": "foo", "color": "red"}' \ https://docs-examples.firebaseio.com/rest/securing-data/example.json # SUCCESS (assuming 'blue' appears in our colors list) curl -X PUT -d '{"size": 21, "color": "blue"}' \ https://docs-examples.firebaseio.com/rest/securing-data/example.json # If the record already exists and has a color, this will # succeed, otherwise it will fail since newData.hasChildren(['color', 'size']) # will fail to validate curl -X PUT -d '99' \ https://docs-examples.firebaseio.com/rest/securing-data/example/size.json
سحابة التخزين
عند تقييم القواعد ، قد ترغب أيضًا في تقييم البيانات الوصفية للملف الجاري تحميله أو تنزيله أو تعديله أو حذفه. يتيح لك ذلك إنشاء قواعد معقدة وقوية تقوم بأشياء مثل السماح فقط بتحميل الملفات ذات أنواع محتويات معينة ، أو حذف الملفات التي يزيد حجمها عن حجم معين فقط.
يحتوي كائن resource
على أزواج مفتاح / قيمة مع ظهور بيانات وصفية للملف في كائن التخزين السحابي. يمكن فحص هذه الخصائص في طلبات read
أو write
لضمان سلامة البيانات. يتحقق كائن resource
من البيانات الوصفية للملفات الموجودة في حاوية Cloud Storage.
service firebase.storage {
match /b/{bucket}/o {
match /images {
match /{allImages=**} {
// Allow reads if a custom 'visibility' field is set to 'public'
allow read: if resource.metadata.visibility == 'public';
}
}
}
}
يمكنك أيضًا استخدام كائن request.resource
في طلبات write
(مثل عمليات التحميل وتحديثات البيانات الوصفية والحذف. يحصل كائن request.resource
على بيانات وصفية من الملف الذي سيتم كتابته إذا كان مسموحًا write
.
يمكنك استخدام هاتين القيمتين لمنع التحديثات غير المرغوب فيها أو غير المتسقة أو لفرض قيود التطبيق ، مثل نوع الملف أو حجمه.
service firebase.storage {
match /b/{bucket}/o {
match /images {
// Cascade read to any image type at any path
match /{allImages=**} {
allow read;
}
// Allow write files to the path "images/*", subject to the constraints:
// 1) File is less than 5MB
// 2) Content type is an image
// 3) Uploaded content type matches existing content type
// 4) File name (stored in imageId wildcard variable) is less than 32 characters
match /{imageId} {
allow write: if request.resource.size < 5 * 1024 * 1024
&& request.resource.contentType.matches('image/.*')
&& request.resource.contentType == resource.contentType
&& imageId.size() < 32
}
}
}
}
تتوفر قائمة كاملة بالخصائص في كائن resource
في الوثائق المرجعية .