Anda dapat menggunakan Aturan Keamanan Firebase untuk menulis data baru secara bersyarat berdasarkan data yang ada di database atau bucket penyimpanan Anda. Anda juga dapat menulis aturan yang memberlakukan validasi data dengan membatasi penulisan berdasarkan data baru yang sedang ditulis. Baca terus untuk mempelajari lebih lanjut tentang aturan yang menggunakan data yang ada untuk membuat kondisi keamanan.
Pilih produk di setiap bagian untuk mempelajari lebih lanjut tentang aturan validasi data.
Pembatasan pada data baru
Toko Api Awan
Jika Anda ingin memastikan bahwa dokumen yang berisi bidang tertentu tidak dibuat, Anda dapat menyertakan bidang tersebut dalam kondisi yang allow
. Misalnya, jika Anda ingin menolak pembuatan dokumen apa pun yang berisi bidang ranking
, Anda akan melarangnya dalam kondisi create
.
service cloud.firestore {
match /databases/{database}/documents {
// Disallow
match /cities/{city} {
allow create: if !("ranking" in request.resource.data)
}
}
}
Basis Data Waktu Nyata
Jika Anda ingin memastikan bahwa data yang berisi nilai tertentu tidak ditambahkan ke database Anda, Anda akan memasukkan nilai tersebut ke dalam aturan Anda dan melarangnya untuk menulis. Misalnya, jika Anda ingin menolak penulisan apa pun yang berisi nilai ranking
, Anda akan melarang penulisan untuk dokumen apa pun dengan nilai 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')
}
}
Penyimpanan awan
Jika Anda ingin memastikan bahwa file yang berisi metadata tertentu tidak dibuat, Anda dapat menyertakan metadata dalam kondisi allow
. Misalnya, jika Anda ingin menolak pembuatan file apa pun yang berisi metadata ranking
, Anda akan melarangnya dalam kondisi create
.
service firebase.storage {
match /b/{bucket}/o {
match /files/{allFiles=**} {
// Disallow
allow create: if !("ranking" in request.resource.metadata)
}
}
}
Gunakan data yang ada di Aturan Keamanan Firebase
Toko Api Awan
Banyak aplikasi menyimpan informasi kontrol akses sebagai bidang pada dokumen di database. Aturan Keamanan Cloud Firestore dapat mengizinkan atau menolak akses secara dinamis berdasarkan data dokumen:
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';
}
}
}
Variabel resource
mengacu pada dokumen yang diminta, dan resource.data
adalah peta dari semua bidang dan nilai yang disimpan dalam dokumen. Untuk informasi lebih lanjut tentang variabel resource
, lihat dokumentasi referensi .
Saat menulis data, Anda mungkin ingin membandingkan data yang masuk dengan data yang sudah ada. Ini memungkinkan Anda melakukan hal-hal seperti memastikan bidang tidak berubah, bahwa bidang hanya bertambah satu, atau bahwa nilai baru setidaknya satu minggu ke depan. Dalam hal ini, jika kumpulan aturan Anda mengizinkan penulisan tertunda, variabel request.resource
berisi status dokumen di masa mendatang. Untuk operasi update
yang hanya mengubah subset bidang dokumen, variabel request.resource
akan berisi status dokumen tertunda setelah operasi. Anda dapat memeriksa nilai bidang di request.resource
untuk mencegah pembaruan data yang tidak diinginkan atau tidak konsisten:
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;
}
}
}
Basis Data Waktu Nyata
Di Realtime Database, gunakan aturan .validate
untuk menerapkan struktur data dan memvalidasi format dan konten data. Aturan menjalankan aturan .validate
setelah memverifikasi bahwa aturan .write
memberikan akses.
Aturan .validate
tidak mengalir. Jika ada aturan validasi yang gagal pada jalur atau subjalur mana pun dalam aturan, seluruh operasi tulis akan ditolak. Selain itu, definisi validasi hanya memeriksa nilai non-null, dan selanjutnya mengabaikan permintaan apa pun yang menghapus data.
Pertimbangkan aturan .validate
berikut:
{
"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()"
}
}
}
}
Tulis permintaan ke database dengan aturan di atas akan memiliki hasil sebagai berikut:
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];
Cepat
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);
Jawa
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);
ISTIRAHAT
# 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
Penyimpanan awan
Saat mengevaluasi aturan, Anda mungkin juga ingin mengevaluasi metadata file yang sedang diunggah, diunduh, diubah, atau dihapus. Ini memungkinkan Anda untuk membuat aturan yang kompleks dan kuat yang melakukan hal-hal seperti hanya mengizinkan file dengan tipe konten tertentu untuk diunggah, atau hanya file yang berukuran lebih besar dari ukuran tertentu yang akan dihapus.
Objek resource
berisi pasangan kunci/nilai dengan metadata file yang muncul di objek Cloud Storage. Properti ini dapat diperiksa pada permintaan read
atau write
untuk memastikan integritas data. Objek resource
memeriksa metadata pada file yang ada di bucket Cloud Storage Anda.
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';
}
}
}
}
Anda juga dapat menggunakan objek request.resource
pada permintaan write
(seperti unggahan, pembaruan metadata, dan penghapusan. Objek request.resource
mendapatkan metadata dari file yang akan ditulis jika write
diizinkan.
Anda dapat menggunakan kedua nilai ini untuk mencegah pembaruan yang tidak diinginkan atau tidak konsisten atau untuk menerapkan batasan aplikasi, seperti jenis atau ukuran file.
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
}
}
}
}
Daftar lengkap properti di objek resource
tersedia di dokumentasi referensi .