التحقُّق من صحة البيانات

يمكنك استخدام قواعد أمان 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);
ج موضوعية
ملاحظة: منتج Firebase هذا غير متوفر في هدف App Clip.
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];
سويفت
ملاحظة: منتج Firebase هذا غير متوفر في هدف App Clip.
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 في الوثائق المرجعية .