Panduan ini dikembangkan dari panduan mempelajari sintaksis inti dari bahasa Aturan Keamanan Firebase untuk menunjukkan cara menambahkan kondisi dalam Aturan Keamanan Firebase untuk Cloud Storage.
Elemen penyusun utama Aturan Keamanan Cloud Storage adalah kondisi.
Kondisi adalah ekspresi boolean yang menentukan apakah operasi tertentu
diizinkan atau ditolak. Untuk aturan dasar, penggunaan literal true
dan false
sebagai kondisi berfungsi dengan sangat baik. Namun, bahasa Aturan Keamanan Firebase untuk Cloud Storage
memberi Anda cara untuk menulis kondisi lebih kompleks yang dapat:
- Memeriksa autentikasi pengguna
- Memvalidasi data yang masuk
Authentication
Aturan Keamanan Firebase untuk Cloud Storage terintegrasi dengan Firebase Authentication guna menyediakan autentikasi berbasis pengguna yang andal untuk Cloud Storage. Hal ini memungkinkan kontrol akses terperinci berdasarkan klaim token Firebase Authentication.
Saat pengguna terautentikasi membuat permintaan ke Cloud Storage,
variabel request.auth
akan diisi dengan uid
(request.auth.uid
) pengguna serta klaim JWT Firebase Authentication
(request.auth.token
).
Selain itu, saat menggunakan autentikasi kustom, klaim tambahan akan muncul
di kolom request.auth.token
.
Saat pengguna tanpa autentikasi membuat permintaan, variabel request.auth
adalah
null
.
Dengan menggunakan data ini, ada beberapa cara umum menggunakan autentikasi untuk mengamankan file:
- Publik: abaikan
request.auth
- Pribadi terautentikasi: pastikan
request.auth
bukannull
- Pribadi pengguna: pastikan
request.auth.uid
sama dengan jaluruid
- Pribadi grup: pastikan klaim token kustom cocok dengan klaim yang dipilih, atau baca metadata file untuk melihat apakah ada kolom metadata atau tidak
Publik
Setiap aturan yang tidak mempertimbangkan konteks request.auth
dapat dianggap sebagai
aturan public
, karena tidak mempertimbangkan konteks autentikasi pengguna.
Aturan ini dapat berguna untuk menampilkan data publik seperti aset game, file suara,
atau konten statis lainnya.
// Anyone to read a public image if the file is less than 100kB // Anyone can upload a public file ending in '.txt' match /public/{imageId} { allow read: if resource.size < 100 * 1024; allow write: if imageId.matches(".*\\.txt"); }
Pribadi terautentikasi
Dalam kasus tertentu, Anda mungkin ingin agar data dapat dilihat oleh semua pengguna aplikasi yang terautentikasi,
tetapi tidak oleh pengguna tanpa autentikasi. Karena variabel request.auth
adalah null
untuk semua pengguna tanpa autentikasi, Anda hanya perlu memastikan bahwa
variabel request.auth
ada untuk mengharuskan autentikasi:
// Require authentication on all internal image reads match /internal/{imageId} { allow read: if request.auth != null; }
Pribadi pengguna
Sejauh ini, kasus penggunaan request.auth
yang paling umum adalah memberikan
izin terperinci kepada pengguna individual pada file mereka: mulai dari mengupload gambar profil hingga membaca dokumen pribadi.
Karena file di Cloud Storage memiliki "jalur" lengkap ke file, yang diperlukan
untuk membuat file dikontrol oleh pengguna adalah bagian dari informasi identifikasi pengguna yang unik pada awalan nama file (seperti uid
pengguna) yang dapat diperiksa saat aturan dievaluasi:
// Only a user can upload their profile picture, but anyone can view it match /users/{userId}/profilePicture.png { allow read; allow write: if request.auth.uid == userId; }
Grup pribadi
Kasus penggunaan umum lainnya adalah memberikan izin grup pada suatu objek, seperti mengizinkan beberapa anggota tim untuk berkolaborasi pada dokumen bersama. Ada beberapa pendekatan untuk melakukan hal ini:
- Membuat token kustom Firebase Authentication yang berisi informasi tambahan mengenai anggota grup (seperti ID grup)
- Menyertakan informasi grup (seperti ID grup atau daftar
uid
yang diberi otorisasi) di metadata file
Setelah disimpan dalam token atau metadata file, data ini dapat direferensikan dari dalam aturan:
// 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; }
Evaluasi Permintaan
Upload, download, perubahan metadata, dan penghapusan dievaluasi menggunakan
request
yang dikirim ke Cloud Storage. Selain ID unik pengguna dan
payload Firebase Authentication di objek request.auth
seperti yang dideskripsikan di atas,
variabel request
berisi jalur file tempat permintaan akan dijalankan, waktu saat permintaan diterima, dan nilai
resource
baru jika permintaan tersebut adalah permintaan tulis.
Objek request
juga berisi ID unik pengguna dan payload Firebase Authentication di objek request.auth
, yang akan dijelaskan lebih lanjut di bagian Keamanan Berbasis Pengguna dalam dokumentasi.
Daftar lengkap properti di objek request
tersedia di bawah:
Properti | Jenis | Deskripsi |
---|---|---|
auth |
map<string, string> | Saat pengguna login, memberikan uid , ID unik pengguna, dan
token , peta klaim JWT Firebase Authentication. Jika pengguna tidak login, nilainya adalah
null . |
params |
map<string, string> | Peta yang memuat parameter kueri permintaan. |
path |
jalur | path yang mewakili jalur tempat permintaan
dijalankan. |
resource |
map<string, string> | Nilai resource baru, hanya ada pada permintaan write .
|
time |
timestamp | Stempel waktu yang menunjukkan waktu server ketika permintaan dievaluasi. |
Evaluasi Resource
Saat mengevaluasi aturan, Anda mungkin juga ingin mengevaluasi metadata dari file yang diupload, didownload, diubah, atau dihapus. Dengan begitu, Anda dapat membuat aturan yang rumit dan kuat untuk melakukan hal spesifik, seperti hanya mengizinkan upload file dengan jenis konten tertentu atau penghapusan file dengan ukuran lebih besar dari ukuran tertentu.
Aturan Keamanan Firebase untuk Cloud Storage menyediakan metadata file di objek resource
,
yang berisi key-value pair dari metadata yang muncul pada
objek Cloud Storage. Properti ini dapat diinspeksi pada permintaan read
atau
write
untuk memastikan integritas data.
Pada permintaan write
(seperti upload, pembaruan metadata, dan penghapusan),
selain objek resource
, yang berisi metadata file untuk file
yang saat ini ada di jalur permintaan, Anda juga dapat menggunakan objek
request.resource
, yang berisi subset metadata file yang
akan ditulis jika operasi tulis diizinkan. Anda dapat menggunakan kedua nilai tersebut untuk
memastikan integritas data atau memberlakukan pembatasan aplikasi, seperti jenis atau ukuran file.
Daftar lengkap properti di objek resource
tersedia di bawah:
Properti | Jenis | Deskripsi |
---|---|---|
name |
string | Nama lengkap objek |
bucket |
string | Nama bucket yang ditempati objek ini. |
generation |
int | Google Cloud Storage object generation untuk objek ini. |
metageneration |
int | Google Cloud Storage object metageneration untuk objek ini. |
size |
int | Ukuran objek, dalam byte. |
timeCreated |
timestamp | Stempel waktu yang menunjukkan kapan objek dibuat. |
updated |
timestamp | Stempel waktu yang menunjukkan kapan objek terakhir diperbarui. |
md5Hash |
string | Hash MD5 untuk objek ini. |
crc32c |
string | Hash crc32c untuk objek ini. |
etag |
string | Etag yang terkait dengan objek ini. |
contentDisposition |
string | Disposisi konten yang terkait dengan objek ini. |
contentEncoding |
string | Encoding konten yang terkait dengan objek ini. |
contentLanguage |
string | Bahasa konten yang terkait dengan objek ini. |
contentType |
string | Jenis konten yang terkait dengan objek ini. |
metadata |
map<string, string> | Key-value pair untuk metadata kustom tambahan yang ditetapkan developer. |
request.resource
berisi semua properti di atas kecuali generation
, metageneration
, etag
, timeCreated
, dan updated
.
Meningkatkan kualitas aturan dengan Cloud Firestore
Anda dapat mengakses dokumen di Cloud Firestore untuk mengevaluasi kriteria otorisasi lainnya.
Aturan keamanan Anda dapat memanfaatkan fungsi firestore.get()
dan firestore.exists()
untuk mengevaluasi permintaan yang masuk berdasarkan dokumen di Cloud Firestore.
Fungsi firestore.get()
dan firestore.exists()
sama-sama memerlukan jalur dokumen yang ditentukan secara lengkap. Ketika menggunakan variabel untuk membuat jalur bagi firestore.get()
dan firestore.exists()
, Anda harus meng-escape variabel secara eksplisit menggunakan sintaksis $(variable)
.
Pada contoh di bawah, kita melihat aturan yang membatasi akses baca ke file kepada pengguna yang merupakan anggota klub tertentu.
service firebase.storage { match /b/{bucket}/o { match /users/{club}/files/{fileId} { allow read: if club in firestore.get(/databases/(default)/documents/users/$(request.auth.id)).memberships } } }Pada contoh berikutnya, hanya teman pengguna yang dapat melihat fotonya.
service firebase.storage { match /b/{bucket}/o { match /users/{userId}/photos/{fileId} { allow read: if firestore.exists(/databases/(default)/documents/users/$(userId)/friends/$(request.auth.id)) } } }
Setelah membuat dan menyimpan Aturan Keamanan Cloud Storage pertama yang menggunakan fungsi Cloud Firestore ini, Anda akan diminta mengaktifkan izin untuk menghubungkan kedua produk tersebut di Firebase console atau Firebase CLI.
Anda dapat menonaktifkan fitur ini dengan menghapus peran IAM, seperti yang dijelaskan dalam Mengelola dan men-deploy Aturan Keamanan Firebase.
Memvalidasi data
Aturan Keamanan Firebase untuk Cloud Storage juga dapat digunakan untuk validasi data,
termasuk memvalidasi nama dan jalur file, serta properti metadata file
seperti contentType
dan size
.
service firebase.storage { match /b/{bucket}/o { match /images/{imageId} { // Only allow uploads of any image file that's less than 5MB allow write: if request.resource.size < 5 * 1024 * 1024 && request.resource.contentType.matches('image/.*'); } } }
Fungsi kustom
Saat Aturan Keamanan Firebase Anda menjadi makin kompleks, Anda mungkin ingin menggabungkan kumpulan kondisi ke dalam fungsi yang dapat digunakan kembali di seluruh kumpulan aturan. Aturan keamanan mendukung fungsi kustom. Sintaksis untuk fungsi kustom mirip dengan JavaScript, tetapi fungsi Aturan Keamanan Firebase ditulis dalam bahasa khusus domain yang memiliki beberapa batasan penting:
- Fungsi hanya dapat berisi satu pernyataan
return
. Fungsi tidak boleh berisi logika lain apa pun. Misalnya, fungsi tidak dapat menjalankan loop atau memanggil layanan eksternal. - Fungsi dapat secara otomatis mengakses fungsi dan variabel dari cakupan tempat ditetapkannya. Misalnya, fungsi yang ditetapkan dalam
cakupan
service firebase.storage
memiliki akses ke variabelresource
, dan khusus Cloud Firestore, fungsi bawaan sepertiget()
danexists()
. - Fungsi dapat memanggil fungsi lain tetapi tidak secara berulang. Total kedalaman stack panggilan dibatasi sampai 10.
- Pada versi
rules2
, fungsi dapat menentukan variabel menggunakan kata kuncilet
. Fungsi dapat memiliki berapa pun binding let, tetapi harus diakhiri dengan pernyataan return.
Fungsi ditetapkan dengan kata kunci function
dan menerima nol argumen atau
lebih. Misalnya, Anda mungkin ingin menggabungkan dua jenis kondisi yang digunakan
dalam contoh di atas menjadi sebuah fungsi:
service firebase.storage {
match /b/{bucket}/o {
// 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 /images/{imageId} {
allow read, write: if signedInOrPublic();
}
match /mp3s/{mp3Ids} {
allow read: if signedInOrPublic();
}
}
}
Dengan menggunakan fungsi, Aturan Keamanan Firebase akan lebih mudah dipertahankan seiring semakin kompleksnya aturan.
Langkah berikutnya
Setelah membaca pembahasan kondisi di atas, Anda telah memiliki pemahaman yang lebih mendalam tentang Aturan dan siap untuk:
Mempelajari cara menangani kasus penggunaan inti, dan mempelajari alur kerja untuk mengembangkan, menguji, dan men-deploy Aturan:
- Menulis aturan yang menangani skenario umum.
- Mengembangkan pengetahuan dengan meninjau situasi saat Anda harus menemukan dan menghindari Aturan yang tidak aman.
- Menguji aturan menggunakan emulator Cloud Storage dan library pengujian Aturan Keamanan khusus.
- Meninjau metode yang tersedia untuk men-deploy Aturan.