基本安全性規則

Firebase Security Rules 可讓您控管儲存資料的存取權。靈活的規則語法可讓您建立任何符合條件的規則,從所有寫入整個資料庫的作業,到特定文件的作業皆可。

本指南說明在設定應用程式及保護資料時,您可能要實作的幾種較基本用途。不過,在開始撰寫規則之前,建議您進一步瞭解規則的語言行為

如要存取及更新規範,請按照「管理及部署 Firebase Security Rules」一文中的步驟操作。

預設規則:鎖定模式

Firebase 控制台中建立資料庫或儲存空間執行個體時,您可以選擇 Firebase Security Rules 限制資料存取權 (鎖定模式) 或允許任何人存取 (測試模式)。在 Cloud FirestoreRealtime 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 DatabaseCloud Storage 中,規則無法使用 Cloud Firestore 規則可納入的 get() 方法。因此,您必須建構資料庫或檔案中繼資料,以反映您在規則中使用的屬性。

如要設定這項規則:Cloud Firestore 中,在使用者的文件中加入可供您讀取的欄位,然後設定規則,以便讀取該欄位並有條件地授予存取權。在 Realtime Database 中,建立用於定義應用程式使用者的資料路徑,並在子節點中授予使用者角色。

您也可以Authentication 中設定自訂宣告,然後從任何 Firebase Security Rules 中的 auth.token 變數擷取該資訊。

資料定義的屬性和角色

這些規則僅適用於 Cloud FirestoreRealtime 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;
  }
}