Firebase Security Rules 可讓您控管儲存資料的存取權。靈活的規則語法可讓您建立任何符合條件的規則,從所有寫入整個資料庫的作業,到特定文件的作業皆可。
本指南說明在設定應用程式及保護資料時,您可能要實作的幾種較基本用途。不過,在開始撰寫規則之前,建議您進一步瞭解規則的語言和行為。
如要存取及更新規範,請按照「管理及部署 Firebase Security Rules」一文中的步驟操作。
預設規則:鎖定模式
在 Firebase 控制台中建立資料庫或儲存空間執行個體時,您可以選擇 Firebase Security Rules 限制資料存取權 (鎖定模式) 或允許任何人存取 (測試模式)。在 Cloud Firestore 和 Realtime Database 中,鎖定模式的預設規則會拒絕所有使用者存取。在 Cloud Storage 中,只有經過驗證的使用者可以存取儲存空間值區。
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;
}
}
}
開發環境規則
在您處理應用程式時,可能會需要相對開放或不受限制的資料存取權。只要確保在將應用程式部署至正式版前更新 Rules 即可。另外請注意,即使您尚未發布應用程式,只要部署應用程式,就會開放給大眾存取。
請注意,Firebase 允許用戶端直接存取您的資料,而 Firebase Security Rules 是唯一可阻擋惡意使用者存取資料的安全防護機制。將規則與產品邏輯分開定義有許多優點:客戶不必負責執行安全性,錯誤的實作不會危害您的資料,最重要的是,您不必依賴中介伺服器來保護資料。
所有已驗證的使用者
我們不建議讓任何已登入的使用者存取您的資料,但建議您在開發應用程式時設定任何已驗證使用者的存取權。
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;
}
}
}
正式版規則
準備部署應用程式時,請務必確保資料受到保護,並且適當授予使用者存取權。利用 Authentication 設定以使用者為依據的存取權,並直接從資料庫讀取資料,以便設定以資料為依據的存取權。
建議您在建構資料時撰寫規則,因為設定規則的方式會影響您限制不同路徑資料存取權的方式。
僅限內容擁有者存取
這些規則會限制存取權,只允許已驗證的內容擁有者存取。只有一位使用者可以讀取及寫入資料,且資料路徑包含使用者 ID。
這項規則適用的情況:如果資料是按使用者分隔,也就是只有建立資料的使用者才能存取資料,這項規則就很實用。
不適用情況:如果有多位使用者需要寫入或讀取相同資料,這套規則集就無法運作,使用者會覆寫資料,或無法存取自己建立的資料。
設定這項規則的方式:建立規則,確認要求讀取或寫入資料存取權的使用者,就是擁有該資料的使用者。
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;
}
}
}
混合式公開與私人存取
這項規則可讓任何人讀取資料集,但限定只能向通過驗證的內容擁有者建立或修改特定路徑的資料。
適用情況:如果應用程式需要可供大眾閱讀的元素,但需要限制這些元素擁有者的編輯存取權,這項規則就很實用。例如聊天應用程式或網誌。
這項規則不會發揮作用:就像只有內容擁有者規則一樣,如有多位使用者需要編輯相同的資料,這個規則集將無法運作。使用者最終會彼此覆寫資料。
設定這項規則:建立規則,為所有使用者 (或所有已驗證的使用者) 啟用讀取權限,並確認寫入資料的使用者是擁有者。
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
// Allow public read access, but only content owners can write
match /some_collection/{document} {
// Allow public reads
allow read: if true
// Allow creation if the current user owns the new document
allow create: if request.auth.uid == request.resource.data.author_uid;
// Allow updates by the owner, and prevent change of ownership
allow update: if request.auth.uid == request.resource.data.author_uid
&& request.auth.uid == resource.data.author_uid;
// Allow deletion if the current user owns the existing document
allow 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;
}
}
}
以屬性和角色為基礎的存取權
如要讓這些規則生效,您必須在資料中定義屬性並指派給使用者。Firebase Security Rules 會根據資料庫或檔案的中繼資料檢查要求,藉此確認或拒絕存取。
這項規則適用的情況:如果您要為使用者指派角色,這項規則可讓您輕鬆根據角色或特定使用者群組限制存取權。舉例來說,如果您儲存成績,就可以為「學生」群組 (只能讀取其內容)、「老師」群組 (在主題中讀取和寫入) 和「主體」群組 (讀取所有內容) 指派不同的存取層級。
這項規則無法運作時:在 Realtime Database 和 Cloud Storage 中,規則無法使用 Cloud Firestore 規則可納入的 get()
方法。因此,您必須建構資料庫或檔案中繼資料,以反映您在規則中使用的屬性。
如要設定這項規則:在 Cloud Firestore 中,在使用者的文件中加入可供您讀取的欄位,然後設定規則,以便讀取該欄位並有條件地授予存取權。在 Realtime Database 中,建立用於定義應用程式使用者的資料路徑,並在子節點中授予使用者角色。
您也可以在 Authentication 中設定自訂宣告,然後從任何 Firebase Security Rules 中的 auth.token
變數擷取該資訊。
資料定義的屬性和角色
這些規則僅適用於 Cloud Firestore 和 Realtime Database。
Cloud Firestore
請注意,只要規則包含讀取作業 (例如下列規則),系統就會向您收取 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
}
}
}
}
自訂宣稱屬性和角色
如要實作這些規則,請在 Firebase Authentication 中設定自訂憑證附加資訊,然後在規則中使用聲明。
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;
}
}
租用戶屬性
如要實作這些規則,請在 Google Cloud Identity Platform (GCIP) 中設定多用戶群,然後在規則中運用租用戶。以下範例允許在特定用戶群中寫入使用者資料,例如 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;
}
}