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