Menyusun Struktur Aturan Keamanan Cloud Firestore

Cloud Firestore Security Rules memungkinkan Anda mengontrol akses ke dokumen dan koleksi di database. Dengan sintaks aturan yang fleksibel, Anda dapat membuat aturan yang cocok dengan apa pun, dari penulisan ke seluruh database hingga operasi pada dokumen tertentu.

Panduan ini menjelaskan struktur dan sintaksis dasar aturan keamanan. Gabungkan sintaksis ini dengan kondisi aturan keamanan untuk membuat seperangkat aturan lengkap.

Deklarasi layanan dan database

Cloud Firestore Security Rules selalu dimulai dengan deklarasi berikut:

service cloud.firestore {
  match /databases/{database}/documents {
    // ...
  }
}

Deklarasi service cloud.firestore mencakup aturan untuk Cloud Firestore, mencegah konflik antara aturan Cloud Firestore Security Rules dan aturan untuk produk lain seperti Cloud Storage.

Deklarasi match /databases/{database}/documents menentukan bahwa aturan harus cocok dengan database Cloud Firestore apa pun dalam project. Saat ini, setiap project hanya memiliki satu database bernama (default).

Aturan baca/tulis dasar

Aturan dasar terdiri atas pernyataan match yang menentukan lokasi dokumen dan detail ekspresi allow saat diizinkan membaca data yang ditentukan:

service cloud.firestore {
  match /databases/{database}/documents {

    // Match any document in the 'cities' collection
    match /cities/{city} {
      allow read: if <condition>;
      allow write: if <condition>;
    }
  }
}

Semua pernyataan kecocokan harus mengarah ke dokumen, bukan koleksi. Pernyataan kecocokan dapat mengarah ke dokumen tertentu, seperti di match /cities/SF atau menggunakan karakter pengganti untuk mengarah ke dokumen apa pun di jalur yang ditentukan, seperti di match /cities/{city}.

Pada contoh di atas, pernyataan kecocokan menggunakan sintaksis karakter pengganti {city}. Artinya, aturan tersebut berlaku untuk setiap dokumen dalam koleksi cities, seperti /cities/SF atau /cities/NYC. Saat ekspresi allow dalam pernyataan kecocokan dievaluasi, variabel city akan diselesaikan menjadi nama dokumen kota, seperti SF atau NYC.

Operasi terperinci

Dalam beberapa situasi, read dan write perlu dipecah menjadi operasi yang lebih terperinci agar memudahkan. Misalnya, aplikasi Anda mungkin ingin memberlakukan kondisi pada pembuatan dokumen yang berbeda dari kondisi pada penghapusan dokumen. Atau, Anda mungkin ingin mengizinkan pembacaan dokumen tunggal, tetapi menolak kueri yang besar.

Aturan read dapat dibagi menjadi get dan list, sementara aturan write dapat dibagi menjadi create, update, dan delete:

service cloud.firestore {
  match /databases/{database}/documents {
    // A read rule can be divided into get and list rules
    match /cities/{city} {
      // Applies to single document read requests
      allow get: if <condition>;

      // Applies to queries and collection read requests
      allow list: if <condition>;
    }

    // A write rule can be divided into create, update, and delete rules
    match /cities/{city} {
      // Applies to writes to nonexistent documents
      allow create: if <condition>;

      // Applies to writes to existing documents
      allow update: if <condition>;

      // Applies to delete operations
      allow delete: if <condition>;
    }
  }
}

Data hierarkis

Data di Cloud Firestore disusun menjadi koleksi dokumen, dan masing-masing dokumen dapat memperluas hierarkinya hingga subkoleksi. Anda perlu memahami interaksi antara aturan keamanan dan data hierarkis.

Ambil contoh situasi ketika setiap dokumen dalam koleksi cities berisi subkoleksi landmarks. Aturan keamanan hanya berlaku di jalur yang cocok, sehingga kontrol akses yang ditetapkan pada koleksi cities tidak berlaku untuk subkoleksi landmarks. Sebagai gantinya, tulis aturan eksplisit untuk mengontrol akses ke subkoleksi:

service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city} {
      allow read, write: if <condition>;

        // Explicitly define rules for the 'landmarks' subcollection
        match /landmarks/{landmark} {
          allow read, write: if <condition>;
        }
    }
  }
}

Saat membuat pernyataan match bertingkat, jalur pernyataan match dalam selalu bersifat relatif terhadap jalur pernyataan match luar. Oleh karena itu, kumpulan aturan berikut adalah setara:

service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city} {
      match /landmarks/{landmark} {
        allow read, write: if <condition>;
      }
    }
  }
}
service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city}/landmarks/{landmark} {
      allow read, write: if <condition>;
    }
  }
}

Karakter pengganti rekursif

Jika Anda ingin aturan diterapkan ke sembarang hierarki bertingkat yang dalam, gunakan sintaksis karakter pengganti rekursif, {name=**}. Contoh:

service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the cities collection as well as any document
    // in a subcollection.
    match /cities/{document=**} {
      allow read, write: if <condition>;
    }
  }
}

Jika menggunakan sintaksis karakter pengganti rekursif, variabel karakter pengganti akan memuat seluruh segmen lokasi yang cocok, meskipun jika dokumen tersebut berada di subkoleksi bertingkat yang dalam. Misalnya, aturan yang tercantum di atas akan cocok dengan dokumen yang terletak di /cities/SF/landmarks/coit_tower, dan nilai variabel document akan menjadi SF/landmarks/coit_tower.

Namun, perlu diperhatikan bahwa perilaku karakter pengganti berulang bergantung pada versi aturan.

Versi 1

Aturan keamanan menggunakan versi 1 secara default. Dalam versi 1, karakter pengganti berulang cocok dengan satu atau beberapa item jalur. Karakter pengganti tersebut tidak cocok dengan jalur yang kosong, sehingga match /cities/{city}/{document=**} cocok dengan dokumen di subkoleksi, bukan di koleksi cities, sedangkan match /cities/{document=**} cocok dengan dokumen dalam koleksi dan subkoleksi cities.

Karakter pengganti berulang harus ada di akhir pernyataan yang cocok.

Versi 2

Pada aturan keamanan versi 2, karakter pengganti berulang cocok dengan nol atau beberapa item jalur. match/cities/{city}/{document=**} mencocokkan dokumen di subkoleksi apa pun serta dokumen di koleksi cities.

Anda harus memilih versi 2 dengan menambahkan rules_version = '2'; di bagian atas aturan keamanan Anda:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the cities collection as well as any document
    // in a subcollection.
    match /cities/{city}/{document=**} {
      allow read, write: if <condition>;
    }
  }
}

Anda dapat memiliki maksimal satu karakter pengganti berulang di setiap pernyataan kecocokan, tetapi dalam versi 2, Anda dapat menempatkan karakter pengganti ini di mana saja dalam pernyataan kecocokan. Contoh:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the songs collection group
    match /{path=**}/songs/{song} {
      allow read, write: if <condition>;
    }
  }
}

Jika menggunakan kueri grup koleksi, Anda harus menggunakan versi 2. Baca bagian mengamankan kueri grup koleksi.

Pernyataan kecocokan yang tumpang tindih

Ada kemungkinan dokumen cocok dengan beberapa pernyataan match. Jika beberapa ekspresi allow cocok dengan suatu permintaan, akses akan diizinkan jika salah satu kondisi tersebut adalah true:

service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the 'cities' collection.
    match /cities/{city} {
      allow read, write: if false;
    }

    // Matches any document in the 'cities' collection or subcollections.
    match /cities/{document=**} {
      allow read, write: if true;
    }
  }
}

Pada contoh di atas, semua operasi baca dan tulis ke koleksi cities akan diizinkan karena aturan kedua selalu true, meskipun aturan pertama selalu false.

Batas aturan keamanan

Perhatikan batas berikut saat menangani aturan keamanan:

Batas Detail
Jumlah maksimum panggilan exists(), get(), dan getAfter() per permintaan
  • 10 untuk permintaan dokumen tunggal dan permintaan kueri.
  • 20 untuk pembacaan, transaksi, dan penulisan batch multidokumen. Batas 10 sebelumnya juga berlaku untuk setiap operasi.

    Misalnya, bayangkan Anda membuat permintaan penulisan batch dengan 3 operasi penulisan, dan aturan keamanan menggunakan 2 panggilan akses dokumen untuk memvalidasi setiap penulisan. Dalam hal ini, setiap penulisan menggunakan 2 dari 10 panggilan aksesnya dan permintaan penulisan batch menggunakan 6 dari 20 panggilan aksesnya.

Melebihi salah satu batas akan menyebabkan error izin ditolak.

Beberapa panggilan akses dokumen dapat disimpan dalam cache, dan panggilan yang disimpan dalam cache tidak diperhitungkan dalam batas tersebut.

Kedalaman maksimum pernyataan match bertingkat 10
Panjang jalur maksimum, pada segmen jalur, yang diizinkan dalam sekumpulan pernyataan match bertingkat 100
Jumlah maksimum variabel tangkapan jalur yang diizinkan dalam sekumpulan pernyataan match bertingkat 20
Kedalaman maksimum panggilan fungsi 20
Jumlah maksimum argumen fungsi 7
Jumlah maksimum binding variabel let per fungsi 10
Jumlah maksimum panggilan fungsi siklis atau berulang 0 &lpar;tidak diizinkan&rpar;
Jumlah maksimum ekspresi yang dievaluasi per permintaan 1.000
Ukuran maksimum kumpulan aturan Kumpulan aturan harus mematuhi dua batas ukuran:
  • Batas 256 KB pada ukuran sumber teks kumpulan aturan yang dipublikasikan dari Firebase console atau dari CLI menggunakan firebase deploy.
  • Batas 250 KB pada ukuran kumpulan aturan yang dikompilasi, yang dihasilkan saat Firebase memproses sumber dan menjadikannya aktif di back-end.

Langkah berikutnya