يمكنك استخدام Firebase Security Rules لكتابة بيانات جديدة بشكل مشروط بناءً على البيانات الحالية. في قاعدة البيانات أو حزمة التخزين. يمكنك أيضًا كتابة قواعد تفرض البيانات. عمليات التحقق عن طريق تقييد عمليات الكتابة بناءً على البيانات الجديدة التي تتم كتابتها. مواصلة القراءة لمعرفة المزيد من المعلومات عن القواعد التي تستخدم البيانات الحالية لإنشاء شروط أمان.
اختَر منتجًا في كل قسم لمعرفة المزيد من المعلومات حول قواعد التحقّق من صحة البيانات.
القيود المفروضة على البيانات الجديدة
Cloud Firestore
إذا كنت ترغب في التأكد من أن المستند الذي يحتوي على حقل معين ليس
يمكنك تضمين الحقل في الشرط allow
. على سبيل المثال، إذا
رفض إنشاء أي مستندات تحتوي على الحقل ranking
،
أنت لا تسمح به في حالة create
.
service cloud.firestore {
match /databases/{database}/documents {
// Disallow
match /cities/{city} {
allow create: if !("ranking" in request.resource.data)
}
}
}
Realtime Database
إذا كنت تريد التأكد من عدم إضافة البيانات التي تحتوي على قيم معينة
إلى قاعدة البيانات، فيمكنك تضمين هذه القيمة في القواعد وعدم السماح بها
يكتب. على سبيل المثال، إذا كنت تريد رفض أي عمليات كتابة تحتوي على 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')
}
}
Cloud Storage
للتأكد من أنّ الملف الذي يحتوي على بيانات وصفية محددة
يمكنك تضمين البيانات الوصفية في الشرط allow
. على سبيل المثال، إذا
رفض إنشاء أي ملفات تحتوي على بيانات ranking
الوصفية
أنت لا تسمح به في حالة create
.
service firebase.storage {
match /b/{bucket}/o {
match /files/{allFiles=**} {
// Disallow
allow create: if !("ranking" in request.resource.metadata)
}
}
}
استخدام البيانات الحالية في Firebase Security Rules
Cloud Firestore
تخزِّن العديد من التطبيقات معلومات التحكم بالوصول كحقول في المستندات في قاعدة البيانات. يمكن لـ Cloud Firestore Security Rules السماح بالوصول أو رفضه ديناميكيًا بناءً على المستند البيانات:
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
في Realtime Database، يمكنك استخدام قواعد .validate
لفرض بنى البيانات والتحقّق من الصحة.
تنسيق البيانات ومحتواها. ينفِّذ Rules قاعدتَين (.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()"
}
}
}
}
سيكون على كتابة الطلبات في قاعدة بيانات باستخدام القواعد أعلاه ما يلي النتائج:
JavaScript
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);
Objective-C
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];
Swift
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);
REST
# 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
Cloud Storage
عند تقييم القواعد، قد تحتاج أيضًا إلى تقييم البيانات الوصفية للملف التي يجري تحميلها أو تنزيلها أو تعديلها أو حذفها. يتيح لك ذلك إنشاء قواعد معقدة وفعالة تعمل على تنفيذ إجراءات مثل السماح بالملفات التي تحتوي على أنواع المحتوى التي سيتم تحميلها، أو الملفات التي يزيد حجمها عن حجم معين فقط حذف.
يحتوي العنصر resource
على أزواج المفتاح/القيمة مع البيانات الوصفية للملف التي تظهر في
كائن Cloud Storage. يمكن فحص هذه السمات على 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
في
المستندات المرجعية