Aturan Keamanan Firebase memungkinkan Anda mengontrol akses ke data yang disimpan. Dengan sintaksis aturan yang fleksibel, Anda dapat membuat aturan yang cocok dengan apa pun, dari semua penulisan ke seluruh database hingga operasi pada dokumen tertentu.
Panduan ini menjelaskan beberapa kasus penggunaan yang lebih mendasar yang mungkin ingin Anda terapkan saat menyiapkan aplikasi dan melindungi data Anda. Namun, sebelum mulai menulis aturan, sebaiknya Anda mempelajari lebih lanjut bahasa dan perilaku aturan tersebut.
Ikuti langkah-langkah yang diuraikan pada Mengelola dan men-deploy Aturan Keamanan Firebase untuk mengakses dan memperbarui aturan Anda.
Aturan default: Mode terkunci
Saat Anda membuat instance penyimpanan atau database di Firebase console, Anda dapat memilih apakah Aturan Keamanan Firebase akan membatasi akses ke data Anda (Mode terkunci) atau memberikan akses kepada semua pengguna (Mode pengujian). Di Cloud Firestore dan Realtime Database, aturan default untuk Mode terkunci menolak akses ke semua pengguna. Di Cloud Storage, hanya pengguna terautentikasi yang dapat mengakses bucket penyimpanan.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
}
}
Realtime Database
{
"rules": {
".read": false,
".write": false
}
}
Cloud Storage
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
Aturan lingkungan pengembangan
Saat mengerjakan aplikasi, Anda mungkin menginginkan akses yang relatif terbuka atau tidak dibatasi ke data Anda. Pastikan untuk memperbarui Aturan Anda sebelum men-deploy aplikasi ke produksi. Ingat juga bahwa jika Anda men-deploy aplikasi, aplikasi tersebut akan dapat diakses secara publik — bahkan jika Anda belum meluncurkannya.
Ingat bahwa Firebase memungkinkan klien mengakses langsung data Anda, dan Aturan Keamanan Firebase adalah satu-satunya pelindung yang memblokir akses oleh pengguna yang bermaksud jahat. Menentukan aturan secara terpisah dari logika produk memiliki sejumlah keuntungan: klien tidak bertanggung jawab untuk memberlakukan keamanan, implementasi yang berisi bug tidak akan merusak data Anda, dan yang paling penting, Anda tidak mengandalkan server perantara untuk melindungi data dari dunia luar.
Semua pengguna terautentikasi
Meskipun kami tidak menganjurkan data Anda dapat diakses oleh setiap pengguna yang login, mungkin ada baiknya Anda menetapkan akses pada pengguna terautentikasi saat sedang mengembangkan aplikasi Anda.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth != null;
}
}
}
Realtime Database
{
"rules": {
".read": "auth.uid !== null",
".write": "auth.uid !== null"
}
}
Cloud Storage
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
Aturan siap produksi
Saat Anda bersiap untuk men-deploy aplikasi, pastikan data Anda terlindungi dan akses diberikan dengan benar kepada pengguna Anda. Manfaatkan Authentication untuk menyiapkan akses berbasis pengguna dan membaca langsung dari database Anda untuk menyiapkan akses berbasis data.
Pertimbangkan untuk menulis aturan saat Anda membuat struktur data, karena cara menyiapkan aturan akan berpengaruh terhadap cara Anda membatasi akses ke data di berbagai jalur.
Akses hanya untuk pemilik konten
Aturan ini membatasi akses hanya ke pemilik konten yang terautentikasi. Data hanya dapat dibaca dan ditulis oleh satu pengguna, dan jalur data berisi ID pengguna tersebut.
Kapan aturan ini berfungsi: Aturan ini berfungsi dengan baik jika data diisolasikan menurut pengguna — jika satu-satunya pengguna yang perlu mengakses data adalah pengguna yang sama yang membuat data.
Kapan aturan ini tidak berfungsi: Kumpulan aturan ini tidak berfungsi ketika beberapa pengguna perlu menulis atau membaca data yang sama — pengguna akan menimpa data atau tidak dapat mengakses data yang mereka buat.
Untuk menyiapkan aturan ini: Buat aturan yang mengonfirmasi bahwa pengguna yang meminta akses untuk membaca atau menulis data adalah pengguna yang memiliki data tersebut.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
// Allow only authenticated content owners access
match /some_collection/{userId}/{documents=**} {
allow read, write: if request.auth != null && request.auth.uid == userId
}
}
}
Realtime Database
{
"rules": {
"some_path": {
"$uid": {
// Allow only authenticated content owners access to their data
".read": "auth !== null && auth.uid === $uid",
".write": "auth !== null && auth.uid === $uid"
}
}
}
}
Cloud Storage
// Grants a user access to a node matching their user ID
service firebase.storage {
match /b/{bucket}/o {
// Files look like: "user/<UID>/path/to/file.txt"
match /user/{userId}/{allPaths=**} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
}
}
Akses publik dan pribadi campuran
Aturan ini memungkinkan siapa pun untuk membaca set data, tetapi membatasi kemampuan untuk membuat atau memodifikasi data pada jalur tertentu hanya kepada pemilik konten yang terautentikasi.
Kapan aturan ini berfungsi: Aturan ini berfungsi dengan baik untuk aplikasi yang membutuhkan elemen yang dapat dibaca oleh umum, tetapi perlu membatasi akses edit ke pemilik elemen tersebut. Misalnya, aplikasi chat atau blog.
Kapan aturan ini tidak berfungsi: Seperti aturan "hanya untuk pemilik konten", kumpulan aturan ini tidak berfungsi ketika banyak pengguna perlu mengedit data yang sama. Pengguna pada akhirnya akan menimpa data satu sama lain.
Untuk menyiapkan aturan ini: Buat aturan yang memungkinkan akses baca untuk semua pengguna (atau semua pengguna yang terautentikasi), dan mengonfirmasi bahwa pengguna yang menulis data adalah pemiliknya.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
// Allow public read access, but only content owners can write
match /some_collection/{document} {
allow read: if true
allow create: if request.auth.uid == request.resource.data.author_uid;
allow update, delete: if request.auth.uid == resource.data.author_uid;
}
}
}
Realtime Database
{
// Allow anyone to read data, but only authenticated content owners can
// make changes to their data
"rules": {
"some_path": {
"$uid": {
".read": true,
// or ".read": "auth.uid !== null" for only authenticated users
".write": "auth.uid === $uid"
}
}
}
}
Cloud Storage
service firebase.storage {
match /b/{bucket}/o {
// Files look like: "user/<UID>/path/to/file.txt"
match /user/{userId}/{allPaths=**} {
allow read;
allow write: if request.auth.uid == userId;
}
}
}
Akses Berbasis atribut dan Berbasis peran
Agar aturan ini dapat berfungsi, Anda harus menentukan dan menetapkan atribut kepada pengguna pada data Anda. Aturan Keamanan Firebase memeriksa permintaan terhadap data dari database atau metadata file untuk mengonfirmasi atau menolak akses.
Kapan aturan ini berfungsi: Jika Anda menetapkan peran kepada pengguna, aturan ini memudahkan Anda membatasi akses berdasarkan peran atau grup pengguna tertentu. Misalnya, jika Anda menyimpan nilai sekolah, Anda dapat menetapkan beberapa tingkat akses untuk grup "siswa" (hanya membaca konten mereka), grup "guru" (membaca dan menulis pada mata pelajaran mereka), dan grup "kepala sekolah" (membaca semua konten).
Kapan aturan ini tidak berfungsi: Pada Realtime Database dan Cloud Storage, aturan Anda tidak dapat memanfaatkan metode get()
yang dapat disertakan oleh aturan Cloud Firestore.
Akibatnya, Anda harus menyusun database atau metadata file agar mencerminkan atribut yang Anda gunakan pada aturan Anda.
Untuk menyiapkan aturan ini: Di Cloud Firestore, sertakan kolom pada dokumen pengguna yang dapat Anda baca, kemudian susun aturan Anda untuk membaca kolom tersebut dan memberi akses bersyarat. Pada Realtime Database, buat jalur data yang menentukan pengguna aplikasi dan memberi mereka peran pada node turunan.
Anda juga dapat menyiapkan klaim kustom pada Authentication, kemudian mengambil informasi tersebut dari variabel auth.token
pada Aturan Keamanan Firebase apa pun.
Atribut dan peran yang ditentukan data
Aturan ini hanya berfungsi di Cloud Firestore dan Realtime Database.
Cloud Firestore
Ingatlah bahwa setiap kali aturan Anda menyertakan pembacaan, seperti aturan di bawah, Anda akan dibebani biaya atas operasi baca di Cloud Firestore.
service cloud.firestore {
match /databases/{database}/documents {
// For attribute-based access control, Check a boolean `admin` attribute
allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true;
allow read: true;
// Alterntatively, for role-based access, assign specific roles to users
match /some_collection/{document} {
allow read: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Reader"
allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Writer"
}
}
}
Realtime Database
{
"rules": {
"some_path": {
"${subpath}": {
//
".write": "root.child('users').child(auth.uid).child('role').val() === 'admin'",
".read": true
}
}
}
}
Atribut dan peran klaim kustom
Untuk menerapkan aturan ini, siapkan klaim kustom pada Firebase Authentication, kemudian manfaatkan klaim tersebut pada aturan Anda.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
// For attribute-based access control, check for an admin claim
allow write: if request.auth.token.admin == true;
allow read: true;
// Alterntatively, for role-based access, assign specific roles to users
match /some_collection/{document} {
allow read: if request.auth.token.reader == "true";
allow write: if request.auth.token.writer == "true";
}
}
}
Realtime Database
{
"rules": {
"some_path": {
"$uid": {
// Create a custom claim for each role or group
// you want to leverage
".write": "auth.uid !== null && auth.token.writer === true",
".read": "auth.uid !== null && auth.token.reader === true"
}
}
}
}
Cloud Storage
service firebase.storage {
// Allow reads if the group ID in your token matches the file metadata's `owner` property
// Allow writes if the group ID is in the user's custom token
match /files/{groupId}/{fileName} {
allow read: if resource.metadata.owner == request.auth.token.groupId;
allow write: if request.auth.token.groupId == groupId;
}
}
Atribut tenant
Untuk menerapkan aturan ini, siapkan multitenancy di Google Cloud Identity Platform (GCIP), lalu manfaatkan tenant di aturan Anda. Contoh berikut mengizinkan penulisan dari pengguna dalam tenant tertentu, misalnya tenant2-m6tyz
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
// For tenant-based access control, check for a tenantID
allow write: if request.auth.token.firebase.tenant == 'tenant2-m6tyz';
allow read: true;
}
}
Realtime Database
{
"rules": {
"some_path": {
"$uid": {
// Only allow reads and writes if user belongs to a specific tenant
".write": "auth.uid !== null && auth.token.firebase.tenant === 'tenant2-m6tyz'",
".read": "auth.uid !== null
}
}
}
}
Cloud Storage
service firebase.storage {
// Only allow reads and writes if user belongs to a specific tenant
match /files/{tenantId}/{fileName} {
allow read: if request.auth != null;
allow write: if request.auth.token.firebase.tenant == tenantId;
}
}