Ikuti semua informasi yang diumumkan di Firebase Summit, dan pelajari bagaimana Firebase dapat membantu Anda mempercepat pengembangan aplikasi dan menjalankan aplikasi dengan percaya diri. Pelajari Lebih Lanjut

Bahasa Aturan Keamanan

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 , dan delete . Metode kenyamanan read dan write 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 , dan delete . Metode kenyamanan read dan write 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 dan write memberikan akses baca dan tulis yang luas, sedangkan aturan validate 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 kenyamanan read and write .
  • 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 dari request.path .
  • Kecocokan lengkap: Pola path cocok dengan seluruh request.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 pernyataan match sebagai string .
  • 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 pernyataan match sebagai objek path .

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 variabel resource dan fungsi bawaan seperti get() dan exists() .
  • 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 kunci let . 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 kenyamanan read and write .
  • 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 dari request.path .
  • Kecocokan lengkap: Pola path cocok dengan seluruh request.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 pernyataan match sebagai string .
  • 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 pernyataan match sebagai objek path .

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 variabel resource dan fungsi bawaan seperti get() dan exists() .
  • 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 kunci let . 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 .