شما میتوانید از 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/{fileName} {
// 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 فقط مقادیر غیر تهی را بررسی میکنند و متعاقباً هر درخواستی را که دادهها را حذف میکند، نادیده میگیرند.
قوانین .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.jsonCloud Storage
هنگام ارزیابی قوانین، ممکن است بخواهید متادیتای فایلی که آپلود، دانلود، تغییر یا حذف میشود را نیز ارزیابی کنید. این به شما امکان میدهد قوانین پیچیده و قدرتمندی ایجاد کنید که کارهایی مانند اجازه آپلود فقط فایلهایی با انواع محتوای خاص یا حذف فقط فایلهای بزرگتر از یک اندازه خاص را انجام میدهند.
شیء resource شامل جفتهای کلید-مقدار با فرادادههای فایل است که در یک شیء Cloud Storage ظاهر میشوند. این ویژگیها را میتوان در درخواستهای read یا write بررسی کرد تا از صحت دادهها اطمینان حاصل شود. شیء resource فرادادههای فایلهای موجود در سطل Cloud Storage شما را بررسی میکند.
service firebase.storage {
match /b/{bucket}/o {
match /images {
match /{fileName} {
// 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 {
// 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) Filename (stored in imageId wildcard variable) is less than 32 characters
match /{imageId} {
allow read;
allow write: if request.resource.size < 5 * 1024 * 1024
&& request.resource.contentType.matches('image/.*')
&& request.resource.contentType == resource.contentType
&& imageId.size() < 32
}
}
}
}
لیست کاملی از ویژگیهای شیء resource در مستندات مرجع موجود است.