Aturan Keamanan Firebase memanfaatkan bahasa khusus yang fleksibel dan andal yang mendukung berbagai kompleksitas dan perincian. Anda dapat membuat Aturan sespesifik atau seumum mungkin untuk aplikasi Anda. Aturan Realtime Database menggunakan sintaks yang terlihat seperti JavaScript dalam struktur JSON. Aturan Cloud Firestore dan Cloud Storage menggunakan bahasa berdasarkan Common Expression Language (CEL) , yang dibangun di atas CEL dengan pernyataan match
dan allow
yang mendukung akses yang diberikan secara bersyarat.
Karena ini adalah bahasa khusus, bagaimanapun, ada kurva belajar. Gunakan panduan ini untuk lebih memahami bahasa Aturan saat Anda mendalami aturan yang lebih kompleks.
Pilih produk untuk mempelajari lebih lanjut aturannya.
Struktur dasar
Toko Api Awan
Aturan Keamanan Firebase di Cloud Firestore dan Cloud Storage menggunakan struktur dan sintaks berikut:
service <<name>> {
// Match the resource path.
match <<path>> {
// Allow the request if the following conditions are true.
allow <<methods>> : if <<condition>>
}
}
Konsep kunci berikut ini penting untuk dipahami saat Anda membuat aturan:
- Permintaan: Metode atau metode yang dipanggil dalam pernyataan
allow
. Ini adalah metode yang Anda izinkan untuk dijalankan. Metode standarnya adalah:get
,list
,create
,update
, dandelete
. Metode kenyamananread
danwrite
memungkinkan akses baca dan tulis yang luas pada database atau jalur penyimpanan yang ditentukan. - Jalur: Database atau lokasi penyimpanan, direpresentasikan sebagai jalur URI.
- Aturan: Pernyataan
allow
, yang menyertakan kondisi yang mengizinkan permintaan jika bernilai benar.
Masing-masing konsep ini dijelaskan lebih rinci di bawah ini.
Penyimpanan awan
Aturan Keamanan Firebase di Cloud Firestore dan Cloud Storage menggunakan struktur dan sintaks berikut:
service <<name>> {
// Match the resource path.
match <<path>> {
// Allow the request if the following conditions are true.
allow <<methods>> : if <<condition>>
}
}
Konsep kunci berikut ini penting untuk dipahami saat Anda membuat aturan:
- Permintaan: Metode atau metode yang dipanggil dalam pernyataan
allow
. Ini adalah metode yang Anda izinkan untuk dijalankan. Metode standarnya adalah:get
,list
,create
,update
, dandelete
. Metode kenyamananread
danwrite
memungkinkan akses baca dan tulis yang luas pada database atau jalur penyimpanan yang ditentukan. - Jalur: Database atau lokasi penyimpanan, direpresentasikan sebagai jalur URI.
- Aturan: Pernyataan
allow
, yang menyertakan kondisi yang mengizinkan permintaan jika bernilai benar.
Masing-masing konsep ini dijelaskan lebih rinci di bawah ini.
Basis Data Waktu Nyata
Dalam Realtime Database, Aturan Keamanan Firebase terdiri dari ekspresi mirip JavaScript yang terdapat dalam dokumen JSON.
Mereka menggunakan sintaks berikut:
{
"rules": {
"<<path>>": {
// Allow the request if the condition for each method is true.
".read": <<condition>>,
".write": <<condition>>,
".validate": <<condition>>
}
}
}
Ada tiga elemen dasar dalam aturan:
- Path: Lokasi database. Ini mencerminkan struktur JSON basis data Anda.
- Permintaan: Ini adalah metode yang digunakan aturan untuk memberikan akses. Aturan
read
danwrite
memberikan akses baca dan tulis yang luas, sedangkan aturanvalidate
bertindak sebagai verifikasi sekunder untuk memberikan akses berdasarkan data yang masuk atau yang ada. - Kondisi: Kondisi yang mengizinkan permintaan jika bernilai benar.
Konstruksi aturan
Toko Api Awan
Elemen dasar aturan di Cloud Firestore dan Cloud Storage adalah sebagai berikut:
- Deklarasi
service
: Mendeklarasikan produk Firebase tempat aturan diterapkan. - Blok
match
: Menentukan jalur di database atau keranjang penyimpanan tempat aturan diterapkan. - Pernyataan
allow
: Memberikan kondisi untuk pemberian akses, dibedakan berdasarkan metode. Metode yang didukung meliputi:get
,list
,create
,update
,delete
, dan metode kenyamananread
andwrite
. - Deklarasi
function
opsional: Memberikan kemampuan untuk menggabungkan dan menggabungkan kondisi untuk digunakan di beberapa aturan.
service
ini berisi satu atau lebih blok match
dengan pernyataan allow
yang menyediakan kondisi pemberian akses ke permintaan. Variabel request
dan resource
tersedia untuk digunakan dalam ketentuan aturan. Bahasa Aturan Keamanan Firebase juga mendukung deklarasi function
.
Versi sintaks
Pernyataan syntax
menunjukkan versi bahasa Aturan Firebase yang digunakan untuk menulis sumber. Versi bahasa terbaru adalah v2
.
rules_version = '2';
service cloud.firestore {
...
}
Jika tidak ada pernyataan rules_version
yang diberikan, aturan Anda akan dievaluasi menggunakan mesin v1
.
Melayani
Deklarasi service
menentukan produk atau layanan Firebase mana yang akan diterapkan aturan Anda. Anda hanya dapat menyertakan satu deklarasi service
per file sumber.
Toko Api Awan
service cloud.firestore {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
Penyimpanan awan
service firebase.storage {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
Jika Anda menentukan aturan untuk Cloud Firestore dan Cloud Storage menggunakan Firebase CLI, Anda harus menyimpannya dalam file terpisah.
Cocok
Blok match
mendeklarasikan pola path
yang cocok dengan jalur untuk operasi yang diminta ( request.path
yang masuk). Badan match
harus memiliki satu atau lebih blok match
bersarang, pernyataan function
allow
Jalur di blok match
bersarang relatif terhadap jalur di blok match
induk.
Pola path
adalah nama seperti direktori yang mungkin menyertakan variabel atau wildcard. Pola path
memungkinkan pencocokan segmen jalur tunggal dan segmen multi jalur. Variabel apa pun yang terikat di path
terlihat dalam lingkup match
atau lingkup bersarang mana pun tempat path
dideklarasikan.
Kecocokan dengan pola path
mungkin sebagian atau seluruhnya:
- Kecocokan sebagian: Pola
path
adalah kecocokan awalan darirequest.path
. - Kecocokan lengkap: Pola
path
cocok dengan seluruhrequest.path
.
Ketika kecocokan lengkap dibuat, aturan di dalam blok dievaluasi. Saat pencocokan parsial dibuat, aturan match
bersarang diuji untuk melihat apakah ada path
bersarang yang akan menyelesaikan pencocokan.
Aturan di setiap match
lengkap dievaluasi untuk menentukan apakah akan mengizinkan permintaan tersebut. Jika ada aturan yang cocok memberikan akses, permintaan tersebut diizinkan. Jika tidak ada aturan yang cocok yang memberikan akses, permintaan ditolak.
// Given request.path == /example/hello/nested/path the following
// declarations indicate whether they are a partial or complete match and
// the value of any variables visible within the scope.
service firebase.storage {
// Partial match.
match /example/{singleSegment} { // `singleSegment` == 'hello'
allow write; // Write rule not evaluated.
// Complete match.
match /nested/path { // `singleSegment` visible in scope.
allow read; // Read rule is evaluated.
}
}
// Complete match.
match /example/{multiSegment=**} { // `multiSegment` == /hello/nested/path
allow read; // Read rule is evaluated.
}
}
Seperti yang ditunjukkan contoh di atas, deklarasi path
mendukung variabel berikut:
- Wildcard segmen tunggal: Variabel wildcard dideklarasikan di jalur dengan membungkus variabel dalam kurung kurawal:
{variable}
. Variabel ini dapat diakses dalam pernyataanmatch
sebagaistring
. - Wildcard rekursif: Wildcard rekursif, atau multi-segmen, mencocokkan beberapa segmen jalur pada atau di bawah jalur. Wildcard ini cocok dengan semua jalur di bawah lokasi yang Anda atur. Anda dapat mendeklarasikannya dengan menambahkan string
=**
di akhir variabel segmen Anda:{variable=**}
. Variabel ini dapat diakses dalam pernyataanmatch
sebagai objekpath
.
Mengizinkan
Blok match
berisi satu atau lebih pernyataan allow
. Ini adalah aturan Anda yang sebenarnya. Anda dapat menerapkan aturan allow
ke satu atau beberapa metode. Ketentuan pada pernyataan allow
harus bernilai benar untuk Cloud Firestore atau Cloud Storage untuk mengabulkan setiap permintaan yang masuk. Anda juga dapat menulis pernyataan yang allow
tanpa syarat, misalnya, allow read
. Namun, jika pernyataan allow
tidak menyertakan kondisi, pernyataan tersebut selalu mengizinkan permintaan untuk metode tersebut.
Jika salah satu aturan yang allow
untuk metode ini terpenuhi, permintaan akan diizinkan. Selain itu, jika aturan yang lebih luas memberikan akses, Aturan memberikan akses dan mengabaikan aturan yang lebih terperinci yang mungkin membatasi akses.
Pertimbangkan contoh berikut, di mana setiap pengguna dapat membaca atau menghapus file mereka sendiri. Aturan yang lebih terperinci hanya mengizinkan penulisan jika pengguna yang meminta penulisan memiliki file dan file tersebut adalah PNG. Seorang pengguna dapat menghapus file apa pun di subjalur — meskipun itu bukan PNG — karena aturan sebelumnya mengizinkannya.
service firebase.storage {
// Allow the requestor to read or delete any resource on a path under the
// user directory.
match /users/{userId}/{anyUserFile=**} {
allow read, delete: if request.auth != null && request.auth.uid == userId;
}
// Allow the requestor to create or update their own images.
// When 'request.method' == 'delete' this rule and the one matching
// any path under the user directory would both match and the `delete`
// would be permitted.
match /users/{userId}/images/{imageId} {
// Whether to permit the request depends on the logical OR of all
// matched rules. This means that even if this rule did not explicitly
// allow the 'delete' the earlier rule would have.
allow write: if request.auth != null && request.auth.uid == userId && imageId.matches('*.png');
}
}
metode
Setiap pernyataan allow
menyertakan metode yang memberikan akses untuk permintaan masuk dari metode yang sama.
metode | Jenis permintaan |
---|---|
Metode kenyamanan | |
read | Semua jenis permintaan baca |
write | Semua jenis permintaan tulis |
Metode standar | |
get | Baca permintaan untuk satu dokumen atau file |
list | Baca permintaan untuk kueri dan koleksi |
create | Tulis dokumen atau file baru |
update | Tulis ke dokumen database yang ada atau perbarui metadata file |
delete | Hapus data |
Anda tidak dapat tumpang tindih dengan metode baca dalam blok match
yang sama atau metode tulis yang bertentangan dalam deklarasi path
yang sama.
Misalnya, aturan berikut akan gagal:
service bad.example {
match /rules/with/overlapping/methods {
// This rule allows reads to all authenticated users
allow read: if request.auth != null;
match another/subpath {
// This secondary, more specific read rule causes an error
allow get: if request.auth != null && request.auth.uid == "me";
// Overlapping write methods in the same path cause an error as well
allow write: if request.auth != null;
allow create: if request.auth != null && request.auth.uid == "me";
}
}
}
Fungsi
Saat aturan keamanan Anda menjadi lebih kompleks, Anda mungkin ingin menggabungkan kumpulan kondisi dalam fungsi yang dapat Anda gunakan kembali di seluruh kumpulan aturan Anda. Aturan keamanan mendukung fungsi kustom. Sintaks untuk fungsi kustom sedikit mirip dengan JavaScript, tetapi fungsi aturan keamanan ditulis dalam bahasa khusus domain yang memiliki beberapa batasan penting:
- Fungsi hanya dapat berisi satu pernyataan
return
. Mereka tidak dapat berisi logika tambahan apa pun. Misalnya, mereka tidak dapat menjalankan loop atau memanggil layanan eksternal. - Fungsi dapat secara otomatis mengakses fungsi dan variabel dari ruang lingkup di mana mereka didefinisikan. Misalnya, fungsi yang ditentukan dalam lingkup
service cloud.firestore
memiliki akses ke variabelresource
dan fungsi bawaan sepertiget()
danexists()
. - Fungsi dapat memanggil fungsi lain tetapi mungkin tidak berulang. Total kedalaman tumpukan panggilan dibatasi hingga 20.
- Dalam aturan versi
v2
, fungsi dapat mendefinisikan variabel menggunakan kata kuncilet
. Fungsi dapat memiliki hingga 10 let binding, tetapi harus diakhiri dengan pernyataan pengembalian.
Suatu fungsi didefinisikan dengan kata kunci function
dan mengambil nol atau lebih argumen. Misalnya, Anda mungkin ingin menggabungkan dua jenis kondisi yang digunakan dalam contoh di atas menjadi satu fungsi:
service cloud.firestore {
match /databases/{database}/documents {
// True if the user is signed in or the requested data is 'public'
function signedInOrPublic() {
return request.auth.uid != null || resource.data.visibility == 'public';
}
match /cities/{city} {
allow read, write: if signedInOrPublic();
}
match /users/{user} {
allow read, write: if signedInOrPublic();
}
}
}
Berikut adalah contoh yang menunjukkan argumen fungsi dan tugas let. Biarkan pernyataan penugasan harus dipisahkan dengan titik koma.
function isAuthorOrAdmin(userId, article) {
let isAuthor = article.author == userId;
let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
return isAuthor || isAdmin;
}
Perhatikan bagaimana penugasan isAdmin
memberlakukan pencarian koleksi admin. Untuk evaluasi malas tanpa memerlukan pencarian yang tidak diperlukan, manfaatkan sifat hubungan arus pendek &&
(DAN) dan ||
(ATAU) perbandingan untuk memanggil fungsi kedua hanya jika isAuthor
terbukti benar (untuk perbandingan &&
) atau salah (untuk perbandingan ||
).
function isAdmin(userId) {
return exists(/databases/$(database)/documents/admins/$(userId));
}
function isAuthorOrAdmin(userId, article) {
let isAuthor = article.author == userId;
// `||` is short-circuiting; isAdmin called only if isAuthor == false.
return isAuthor || isAdmin(userId);
}
Menggunakan fungsi dalam aturan keamanan Anda membuatnya lebih dapat dipertahankan seiring dengan meningkatnya kompleksitas aturan Anda.
Penyimpanan awan
Elemen dasar aturan di Cloud Firestore dan Cloud Storage adalah sebagai berikut:
- Deklarasi
service
: Mendeklarasikan produk Firebase tempat aturan diterapkan. - Blok
match
: Menentukan jalur di database atau keranjang penyimpanan tempat aturan diterapkan. - Pernyataan
allow
: Memberikan kondisi untuk pemberian akses, dibedakan berdasarkan metode. Metode yang didukung meliputi:get
,list
,create
,update
,delete
, dan metode kenyamananread
andwrite
. - Deklarasi
function
opsional: Memberikan kemampuan untuk menggabungkan dan menggabungkan kondisi untuk digunakan di beberapa aturan.
service
ini berisi satu atau lebih blok match
dengan pernyataan allow
yang menyediakan kondisi pemberian akses ke permintaan. Variabel request
dan resource
tersedia untuk digunakan dalam ketentuan aturan. Bahasa Aturan Keamanan Firebase juga mendukung deklarasi function
.
Versi sintaks
Pernyataan syntax
menunjukkan versi bahasa Aturan Firebase yang digunakan untuk menulis sumber. Versi bahasa terbaru adalah v2
.
rules_version = '2';
service cloud.firestore {
...
}
Jika tidak ada pernyataan rules_version
yang diberikan, aturan Anda akan dievaluasi menggunakan mesin v1
.
Melayani
Deklarasi service
menentukan produk atau layanan Firebase mana yang akan diterapkan aturan Anda. Anda hanya dapat menyertakan satu deklarasi service
per file sumber.
Toko Api Awan
service cloud.firestore {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
Penyimpanan awan
service firebase.storage {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
Jika Anda menentukan aturan untuk Cloud Firestore dan Cloud Storage menggunakan Firebase CLI, Anda harus menyimpannya dalam file terpisah.
Cocok
Blok match
mendeklarasikan pola path
yang cocok dengan jalur untuk operasi yang diminta ( request.path
yang masuk). Badan match
harus memiliki satu atau lebih blok match
bersarang, pernyataan function
allow
Jalur di blok match
bersarang relatif terhadap jalur di blok match
induk.
Pola path
adalah nama seperti direktori yang mungkin menyertakan variabel atau wildcard. Pola path
memungkinkan pencocokan segmen jalur tunggal dan segmen multi jalur. Variabel apa pun yang terikat di path
terlihat dalam lingkup match
atau lingkup bersarang mana pun tempat path
dideklarasikan.
Kecocokan dengan pola path
mungkin sebagian atau seluruhnya:
- Kecocokan sebagian: Pola
path
adalah kecocokan awalan darirequest.path
. - Kecocokan lengkap: Pola
path
cocok dengan seluruhrequest.path
.
Ketika kecocokan lengkap dibuat, aturan di dalam blok dievaluasi. Saat pencocokan parsial dibuat, aturan match
bersarang diuji untuk melihat apakah ada path
bersarang yang akan menyelesaikan pencocokan.
Aturan di setiap match
lengkap dievaluasi untuk menentukan apakah akan mengizinkan permintaan tersebut. Jika ada aturan yang cocok memberikan akses, permintaan tersebut diizinkan. Jika tidak ada aturan yang cocok yang memberikan akses, permintaan ditolak.
// Given request.path == /example/hello/nested/path the following
// declarations indicate whether they are a partial or complete match and
// the value of any variables visible within the scope.
service firebase.storage {
// Partial match.
match /example/{singleSegment} { // `singleSegment` == 'hello'
allow write; // Write rule not evaluated.
// Complete match.
match /nested/path { // `singleSegment` visible in scope.
allow read; // Read rule is evaluated.
}
}
// Complete match.
match /example/{multiSegment=**} { // `multiSegment` == /hello/nested/path
allow read; // Read rule is evaluated.
}
}
Seperti yang ditunjukkan contoh di atas, deklarasi path
mendukung variabel berikut:
- Wildcard segmen tunggal: Variabel wildcard dideklarasikan di jalur dengan membungkus variabel dalam kurung kurawal:
{variable}
. Variabel ini dapat diakses dalam pernyataanmatch
sebagaistring
. - Wildcard rekursif: Wildcard rekursif, atau multi-segmen, mencocokkan beberapa segmen jalur pada atau di bawah jalur. Wildcard ini cocok dengan semua jalur di bawah lokasi yang Anda atur. Anda dapat mendeklarasikannya dengan menambahkan string
=**
di akhir variabel segmen Anda:{variable=**}
. Variabel ini dapat diakses dalam pernyataanmatch
sebagai objekpath
.
Mengizinkan
Blok match
berisi satu atau lebih pernyataan allow
. Ini adalah aturan Anda yang sebenarnya. Anda dapat menerapkan aturan allow
ke satu atau beberapa metode. Ketentuan pada pernyataan allow
harus bernilai benar untuk Cloud Firestore atau Cloud Storage untuk mengabulkan setiap permintaan yang masuk. Anda juga dapat menulis pernyataan yang allow
tanpa syarat, misalnya, allow read
. Namun, jika pernyataan allow
tidak menyertakan kondisi, pernyataan tersebut selalu mengizinkan permintaan untuk metode tersebut.
Jika salah satu aturan yang allow
untuk metode ini terpenuhi, permintaan akan diizinkan. Selain itu, jika aturan yang lebih luas memberikan akses, Aturan memberikan akses dan mengabaikan aturan yang lebih terperinci yang mungkin membatasi akses.
Pertimbangkan contoh berikut, di mana setiap pengguna dapat membaca atau menghapus file mereka sendiri. Aturan yang lebih terperinci hanya mengizinkan penulisan jika pengguna yang meminta penulisan memiliki file dan file tersebut adalah PNG. Seorang pengguna dapat menghapus file apa pun di subjalur — meskipun itu bukan PNG — karena aturan sebelumnya mengizinkannya.
service firebase.storage {
// Allow the requestor to read or delete any resource on a path under the
// user directory.
match /users/{userId}/{anyUserFile=**} {
allow read, delete: if request.auth != null && request.auth.uid == userId;
}
// Allow the requestor to create or update their own images.
// When 'request.method' == 'delete' this rule and the one matching
// any path under the user directory would both match and the `delete`
// would be permitted.
match /users/{userId}/images/{imageId} {
// Whether to permit the request depends on the logical OR of all
// matched rules. This means that even if this rule did not explicitly
// allow the 'delete' the earlier rule would have.
allow write: if request.auth != null && request.auth.uid == userId && imageId.matches('*.png');
}
}
metode
Setiap pernyataan allow
menyertakan metode yang memberikan akses untuk permintaan masuk dari metode yang sama.
metode | Jenis permintaan |
---|---|
Metode kenyamanan | |
read | Semua jenis permintaan baca |
write | Semua jenis permintaan tulis |
Metode standar | |
get | Baca permintaan untuk satu dokumen atau file |
list | Baca permintaan untuk kueri dan koleksi |
create | Tulis dokumen atau file baru |
update | Tulis ke dokumen database yang ada atau perbarui metadata file |
delete | Hapus data |
Anda tidak dapat tumpang tindih dengan metode baca dalam blok match
yang sama atau metode tulis yang bertentangan dalam deklarasi path
yang sama.
Misalnya, aturan berikut akan gagal:
service bad.example {
match /rules/with/overlapping/methods {
// This rule allows reads to all authenticated users
allow read: if request.auth != null;
match another/subpath {
// This secondary, more specific read rule causes an error
allow get: if request.auth != null && request.auth.uid == "me";
// Overlapping write methods in the same path cause an error as well
allow write: if request.auth != null;
allow create: if request.auth != null && request.auth.uid == "me";
}
}
}
Fungsi
Saat aturan keamanan Anda menjadi lebih kompleks, Anda mungkin ingin menggabungkan kumpulan kondisi dalam fungsi yang dapat Anda gunakan kembali di seluruh kumpulan aturan Anda. Aturan keamanan mendukung fungsi kustom. Sintaks untuk fungsi kustom sedikit mirip dengan JavaScript, tetapi fungsi aturan keamanan ditulis dalam bahasa khusus domain yang memiliki beberapa batasan penting:
- Fungsi hanya dapat berisi satu pernyataan
return
. Mereka tidak dapat berisi logika tambahan apa pun. Misalnya, mereka tidak dapat menjalankan loop atau memanggil layanan eksternal. - Fungsi dapat secara otomatis mengakses fungsi dan variabel dari ruang lingkup di mana mereka didefinisikan. Misalnya, fungsi yang ditentukan dalam lingkup
service cloud.firestore
memiliki akses ke variabelresource
dan fungsi bawaan sepertiget()
danexists()
. - Fungsi dapat memanggil fungsi lain tetapi mungkin tidak berulang. Total kedalaman tumpukan panggilan dibatasi hingga 20.
- Dalam aturan versi
v2
, fungsi dapat mendefinisikan variabel menggunakan kata kuncilet
. Fungsi dapat memiliki hingga 10 let binding, tetapi harus diakhiri dengan pernyataan pengembalian.
Suatu fungsi didefinisikan dengan kata kunci function
dan mengambil nol atau lebih argumen. Misalnya, Anda mungkin ingin menggabungkan dua jenis kondisi yang digunakan dalam contoh di atas menjadi satu fungsi:
service cloud.firestore {
match /databases/{database}/documents {
// True if the user is signed in or the requested data is 'public'
function signedInOrPublic() {
return request.auth.uid != null || resource.data.visibility == 'public';
}
match /cities/{city} {
allow read, write: if signedInOrPublic();
}
match /users/{user} {
allow read, write: if signedInOrPublic();
}
}
}
Berikut adalah contoh yang menunjukkan argumen fungsi dan tugas let. Biarkan pernyataan penugasan harus dipisahkan dengan titik koma.
function isAuthorOrAdmin(userId, article) {
let isAuthor = article.author == userId;
let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
return isAuthor || isAdmin;
}
Perhatikan bagaimana penugasan isAdmin
memberlakukan pencarian koleksi admin. Untuk evaluasi malas tanpa memerlukan pencarian yang tidak diperlukan, manfaatkan sifat hubungan arus pendek &&
(DAN) dan ||
(ATAU) perbandingan untuk memanggil fungsi kedua hanya jika isAuthor
terbukti benar (untuk perbandingan &&
) atau salah (untuk perbandingan ||
).
function isAdmin(userId) {
return exists(/databases/$(database)/documents/admins/$(userId));
}
function isAuthorOrAdmin(userId, article) {
let isAuthor = article.author == userId;
// `||` is short-circuiting; isAdmin called only if isAuthor == false.
return isAuthor || isAdmin(userId);
}
Menggunakan fungsi dalam aturan keamanan Anda membuatnya lebih dapat dipertahankan seiring dengan meningkatnya kompleksitas aturan Anda.
Basis Data Waktu Nyata
Seperti diuraikan di atas, Aturan Realtime Database menyertakan tiga elemen dasar: lokasi database sebagai cerminan dari struktur JSON database, jenis permintaan, dan kondisi pemberian akses.
Lokasi basis data
Struktur aturan Anda harus mengikuti struktur data yang telah Anda simpan di database Anda. Misalnya, di aplikasi obrolan dengan daftar pesan, Anda mungkin memiliki data seperti ini:
{
"messages": {
"message0": {
"content": "Hello",
"timestamp": 1405704370369
},
"message1": {
"content": "Goodbye",
"timestamp": 1405704395231
},
...
}
}
Aturan Anda harus mencerminkan struktur itu. Sebagai contoh:
{
"rules": {
"messages": {
"$message": {
// only messages from the last ten minutes can be read
".read": "data.child('timestamp').val() > (now - 600000)",
// new messages must have a string content and a number timestamp
".validate": "newData.hasChildren(['content', 'timestamp']) &&
newData.child('content').isString() &&
newData.child('timestamp').isNumber()"
}
}
}
}
Seperti yang ditunjukkan contoh di atas, Aturan Database Realtime mendukung variabel $location
untuk mencocokkan segmen jalur. Gunakan awalan $
di depan segmen jalur Anda untuk mencocokkan aturan Anda dengan simpul anak mana pun di sepanjang jalur.
{
"rules": {
"rooms": {
// This rule applies to any child of /rooms/, the key for each room id
// is stored inside $room_id variable for reference
"$room_id": {
"topic": {
// The room's topic can be changed if the room id has "public" in it
".write": "$room_id.contains('public')"
}
}
}
}
}
Anda juga dapat menggunakan $variable
secara paralel dengan nama jalur konstan.
{
"rules": {
"widget": {
// a widget can have a title or color attribute
"title": { ".validate": true },
"color": { ".validate": true },
// but no other child paths are allowed
// in this case, $other means any key excluding "title" and "color"
"$other": { ".validate": false }
}
}
}
metode
Di Realtime Database, ada tiga jenis aturan. Dua dari jenis aturan ini — read
dan write
— berlaku untuk metode permintaan masuk. Jenis aturan validate
memberlakukan struktur data dan memvalidasi format dan konten data. Aturan menjalankan aturan .validate
setelah memverifikasi bahwa aturan .write
memberikan akses.
Jenis Aturan | |
---|---|
.Baca | Menjelaskan jika dan kapan data diizinkan untuk dibaca oleh pengguna. |
.menulis | Menjelaskan jika dan kapan data diperbolehkan untuk ditulis. |
.mengesahkan | Menentukan seperti apa nilai yang diformat dengan benar, apakah itu memiliki atribut turunan, dan tipe data. |
Secara default, jika tidak ada aturan yang mengizinkannya, akses di jalur ditolak.
Kondisi bangunan
Toko Api Awan
Kondisi adalah ekspresi boolean yang menentukan apakah operasi tertentu harus diizinkan atau ditolak. Variabel request
dan resource
menyediakan konteks untuk kondisi tersebut.
Variabel request
Variabel request
mencakup bidang berikut dan informasi terkait:
request.auth
Token Web JSON (JWT) yang berisi kredensial autentikasi dari Firebase Authentication. auth
autentikasi berisi sekumpulan klaim standar dan klaim khusus apa pun yang Anda buat melalui Firebase Authentication. Pelajari lebih lanjut Aturan Keamanan dan Autentikasi Firebase .
request.method
request.method
dapat berupa salah satu metode standar atau metode kustom. Metode kemudahan read
dan write
juga ada untuk menyederhanakan aturan penulisan yang berlaku untuk semua metode standar hanya baca atau semua tulis saja.
request.params
request.params
menyertakan data apa pun yang tidak secara khusus terkait dengan request.resource
yang mungkin berguna untuk evaluasi. Dalam praktiknya, peta ini harus kosong untuk semua metode standar, dan harus berisi data non-sumber daya untuk metode khusus. Layanan harus berhati-hati agar tidak mengganti nama atau mengubah jenis kunci dan nilai apa pun yang ditampilkan sebagai parameter.
request.path
request.path
adalah jalur untuk resource
target. Jalur ini relatif terhadap layanan. Segmen jalur yang berisi karakter aman non-url seperti /
dikodekan dengan url.
Variabel resource
Sumber resource
adalah nilai saat ini dalam layanan yang direpresentasikan sebagai peta pasangan kunci-nilai. Mereferensikan resource
dalam suatu kondisi akan menghasilkan paling banyak satu pembacaan nilai dari layanan. Pencarian ini akan dihitung terhadap kuota terkait layanan apa pun untuk sumber daya. Untuk get
permintaan, resource
hanya akan menghitung kuota saat ditolak.
Operator dan prioritas operator
Gunakan tabel di bawah sebagai referensi untuk operator dan prioritasnya yang sesuai dalam Aturan untuk Cloud Firestore dan Cloud Storage.
Diberi ekspresi arbitrer a
dan b
, bidang f
, dan indeks i
.
Operator | Keterangan | Asosiatif |
---|---|---|
a[i] a() af | Indeks, panggilan, akses lapangan | kiri ke kanan | !a -a | Negasi unary | kanan ke kiri |
a/ba%ba*b | Operator perkalian | kiri ke kanan |
a+b ab | Operator aditif | kiri ke kanan |
a>ba>=ba | Operator relasional | kiri ke kanan |
a in b | Keberadaan dalam daftar atau peta | kiri ke kanan |
a is type | Jenis perbandingan, di mana type bisa berupa bool, int, float, number, string, list, map, timestamp, duration, path atau latlng | kiri ke kanan |
a==ba!=b | operator perbandingan | kiri ke kanan | a && b | DAN Bersyarat | kiri ke kanan |
a || b | ATAU bersyarat | kiri ke kanan |
a ? true_value : false_value | Ekspresi terner | kiri ke kanan |
Penyimpanan awan
Kondisi adalah ekspresi boolean yang menentukan apakah operasi tertentu harus diizinkan atau ditolak. Variabel request
dan resource
menyediakan konteks untuk kondisi tersebut.
Variabel request
Variabel request
mencakup bidang berikut dan informasi terkait:
request.auth
Token Web JSON (JWT) yang berisi kredensial autentikasi dari Firebase Authentication. auth
autentikasi berisi sekumpulan klaim standar dan klaim khusus apa pun yang Anda buat melalui Firebase Authentication. Pelajari lebih lanjut Aturan Keamanan dan Autentikasi Firebase .
request.method
request.method
dapat berupa salah satu metode standar atau metode kustom. Metode kemudahan read
dan write
juga ada untuk menyederhanakan aturan penulisan yang berlaku untuk semua metode standar hanya baca atau semua tulis saja.
request.params
request.params
menyertakan data apa pun yang tidak secara khusus terkait dengan request.resource
yang mungkin berguna untuk evaluasi. Dalam praktiknya, peta ini harus kosong untuk semua metode standar, dan harus berisi data non-sumber daya untuk metode khusus. Layanan harus berhati-hati agar tidak mengganti nama atau mengubah jenis kunci dan nilai apa pun yang ditampilkan sebagai parameter.
request.path
request.path
adalah jalur untuk resource
target. Jalur ini relatif terhadap layanan. Segmen jalur yang berisi karakter aman non-url seperti /
dikodekan dengan url.
Variabel resource
Sumber resource
adalah nilai saat ini dalam layanan yang direpresentasikan sebagai peta pasangan kunci-nilai. Mereferensikan resource
dalam suatu kondisi akan menghasilkan paling banyak satu pembacaan nilai dari layanan. Pencarian ini akan dihitung terhadap kuota terkait layanan apa pun untuk sumber daya. Untuk get
permintaan, resource
hanya akan menghitung kuota saat ditolak.
Operator dan prioritas operator
Gunakan tabel di bawah sebagai referensi untuk operator dan prioritasnya yang sesuai dalam Aturan untuk Cloud Firestore dan Cloud Storage.
Diberi ekspresi arbitrer a
dan b
, bidang f
, dan indeks i
.
Operator | Keterangan | Asosiatif |
---|---|---|
a[i] a() af | Indeks, panggilan, akses lapangan | kiri ke kanan | !a -a | Negasi unary | kanan ke kiri |
a/ba%ba*b | Operator perkalian | kiri ke kanan |
a+b ab | Operator aditif | kiri ke kanan |
a>ba>=ba | Operator relasional | kiri ke kanan |
a in b | Keberadaan dalam daftar atau peta | kiri ke kanan |
a is type | Jenis perbandingan, di mana type bisa berupa bool, int, float, number, string, list, map, timestamp, duration, path atau latlng | kiri ke kanan |
a==ba!=b | operator perbandingan | kiri ke kanan | a && b | DAN Bersyarat | kiri ke kanan |
a || b | ATAU bersyarat | kiri ke kanan |
a ? true_value : false_value | Ekspresi terner | kiri ke kanan |
Basis Data Waktu Nyata
Kondisi adalah ekspresi boolean yang menentukan apakah operasi tertentu harus diizinkan atau ditolak. Anda dapat menentukan kondisi tersebut di Aturan Realtime Database dengan cara berikut.
Variabel yang telah ditentukan sebelumnya
Ada sejumlah variabel pra-definisi bermanfaat yang dapat diakses di dalam definisi aturan. Berikut adalah ringkasan singkat dari masing-masing:
Variabel yang Ditentukan Sebelumnya | |
---|---|
sekarang | Waktu saat ini dalam milidetik sejak zaman Linux. Ini bekerja sangat baik untuk memvalidasi stempel waktu yang dibuat dengan firebase.database.ServerValue.TIMESTAMP SDK. |
akar | RuleDataSnapshot yang mewakili jalur root di database Firebase seperti yang ada sebelum percobaan operasi. |
Data baru | RuleDataSnapshot yang mewakili data seperti yang akan ada setelah percobaan operasi. Ini termasuk data baru yang sedang ditulis dan data yang ada. |
data | RuleDataSnapshot yang mewakili data sebagaimana adanya sebelum percobaan operasi. |
variabel $ | Jalur wildcard digunakan untuk mewakili id dan kunci anak dinamis. |
autentikasi | Mewakili payload token pengguna yang diautentikasi. |
Variabel ini dapat digunakan di mana saja dalam aturan Anda. Misalnya, aturan keamanan di bawah ini memastikan bahwa data yang ditulis ke node /foo/
harus berupa string yang kurang dari 100 karakter:
{ "rules": { "foo": { // /foo is readable by the world ".read": true, // /foo is writable by the world ".write": true, // data written to /foo must be a string less than 100 characters ".validate": "newData.isString() && newData.val().length < 100" } } }
Aturan berbasis data
Setiap data dalam database Anda dapat digunakan dalam aturan Anda. Dengan menggunakan variabel yang telah ditentukan root
, data
, dan newData
, Anda dapat mengakses jalur apa pun yang akan ada sebelum atau sesudah peristiwa tulis.
Pertimbangkan contoh ini, yang memungkinkan operasi tulis selama nilai dari /allow_writes/
node adalah true
, node induk tidak memiliki set flag readOnly
, dan ada anak bernama foo
dalam data yang baru ditulis:
".write": "root.child('allow_writes').val() === true && !data.parent().child('readOnly').exists() && newData.child('foo').exists()"
Aturan berbasis kueri
Meskipun tidak dapat menggunakan aturan sebagai filter, Anda dapat membatasi akses ke subkumpulan data dengan menggunakan parameter kueri dalam aturan. Gunakan query.
ekspresi dalam aturan Anda untuk memberikan akses baca atau tulis berdasarkan parameter kueri.
Misalnya, aturan berbasis kueri berikut ini menggunakan aturan keamanan berbasis pengguna dan aturan berbasis kueri untuk membatasi akses ke data dalam kumpulan baskets
hanya ke keranjang belanja yang dimiliki pengguna aktif:
"baskets": {
".read": "auth.uid !== null &&
query.orderByChild === 'owner' &&
query.equalTo === auth.uid" // restrict basket access to owner of basket
}
Kueri berikut, yang menyertakan parameter kueri dalam aturan, akan berhasil:
db.ref("baskets").orderByChild("owner")
.equalTo(auth.currentUser.uid)
.on("value", cb) // Would succeed
Namun, kueri yang tidak menyertakan parameter dalam aturan akan gagal dengan error PermissionDenied
:
db.ref("baskets").on("value", cb) // Would fail with PermissionDenied
Anda juga dapat menggunakan aturan berbasis kueri untuk membatasi berapa banyak data yang diunduh klien melalui operasi baca.
Misalnya, aturan berikut membatasi akses baca hanya ke 1000 hasil kueri pertama, seperti yang diurutkan berdasarkan prioritas:
messages: {
".read": "query.orderByKey &&
query.limitToFirst <= 1000"
}
// Example queries:
db.ref("messages").on("value", cb) // Would fail with PermissionDenied
db.ref("messages").limitToFirst(1000)
.on("value", cb) // Would succeed (default order by key)
query.
ekspresi tersedia di Aturan Database Realtime.
Ekspresi aturan berbasis kueri | ||
---|---|---|
Ekspresi | Jenis | Keterangan |
query.orderByKey query.orderByPriority query.orderByValue | boolean | Benar untuk kueri yang diurutkan berdasarkan kunci, prioritas, atau nilai. Salah sebaliknya. |
query.orderByChild | rangkaian batal | Gunakan string untuk mewakili jalur relatif ke simpul anak. Misalnya, query.orderByChild === "address/zip" . Jika kueri tidak diurutkan oleh simpul anak, nilai ini adalah nol. |
query.startAt query.endAt query.equalTo | rangkaian nomor boolean batal | Mengambil batas kueri pelaksana, atau mengembalikan null jika tidak ada batasan yang ditetapkan. |
query.limitToFirst query.limitToLast | nomor batal | Mengambil batas pada kueri pelaksana, atau mengembalikan nol jika tidak ada batas yang ditetapkan. |
Operator
Aturan Realtime Database mendukung sejumlah operator yang dapat Anda gunakan untuk menggabungkan variabel dalam pernyataan kondisi. Lihat daftar lengkap operator dalam dokumentasi referensi .
Menciptakan kondisi
Ketentuan Anda yang sebenarnya akan bervariasi berdasarkan akses yang ingin Anda berikan. Aturan sengaja menawarkan tingkat fleksibilitas yang sangat tinggi, sehingga aturan aplikasi Anda pada akhirnya bisa sesederhana atau serumit yang Anda inginkan.
Untuk beberapa panduan membuat Aturan siap produksi yang sederhana, lihat Aturan Keamanan Dasar .