Melindungi data pengguna

Firebase Security Rules untuk Cloud Storage terintegrasi dengan Firebase Authentication untuk menyediakan autentikasi berbasis pengguna yang andal untuk Cloud Storage. Hal ini memungkinkan kontrol akses terperinci berdasarkan klaim token Firebase Authentication.

Autentikasi pengguna

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 bukan null
  • Pribadi pengguna: pastikan request.auth.uid sama dengan jalur uid
  • 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;
}

Pengguna pribadi

Sejauh ini, kasus penggunaan request.auth yang paling umum adalah memberikan izin terperinci kepada pengguna individual untuk mengakses 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 di jalur 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 != null && 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 tentang 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;
}

Contoh lengkap

Kasus sederhana empat jenis pembatasan autentikasi yang umum ditunjukkan pada contoh di bawah ini:

service firebase.storage {
  match /b/{bucket}/o {
    match /images {
      // Anyone can view any image (no auth, publicly readable)
      match /{allImages=**} {
        allow read;
      }

      // Only authenticated users can write to "public" images
      match /public/{imageId} {
        allow write: if request.auth != null;
      }

      // Only an individual user can write to "their" images
      match /{userId}/{imageId} {
        allow write: if request.auth.uid == userId;
      }

      // Allow a "group" of users to read/write to shared images
      // An owner metadata property on the object contains the groupId for reads
      // A custom token has been minted with a groupId property for writes
      match /{groupId}/{imageId} {
        allow read: if resource.metadata.owner == request.auth.token.groupId;
        allow write: if request.auth.token.groupId == groupId;
      }
    }
  }
}