基本安全性規則

Firebase Security Rules,可讓您控管儲存資料的存取權。彈性規則語法代表您可以建立規則,比對所有項目,包括整個資料庫的所有寫入作業,以及特定文件的作業。

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

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

預設規則:鎖定模式

Firebase 控制台中建立資料庫或儲存空間執行個體時,您可以選擇是否Firebase Security Rules限制資料存取權 (鎖定模式),或允許任何人存取 (測試模式)。在 Cloud FirestoreRealtime Database 中,「鎖定模式」的預設規則會拒絕所有使用者的存取權。在 Cloud Storage 中,只有通過驗證的使用者才能存取儲存空間 bucket。

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 false;
    }
  }
}

開發環境規則

開發應用程式時,您可能希望擁有相對開放或不受限制的資料存取權。請務必在將應用程式部署至正式版前更新 Rules此外,請注意,即使您尚未啟動應用程式,只要部署應用程式,就能公開存取。

請注意,Firebase 允許用戶端直接存取您的資料,而安全規則是唯一能阻擋惡意使用者存取的防護措施。Firebase Security Rules與產品邏輯分開定義規則有許多優點:用戶端不必負責強制執行安全性、有錯誤的實作不會危及資料,最重要的是,您不必依賴中介伺服器來保護資料免於外洩。

所有已驗證的使用者

雖然我們不建議讓任何登入的使用者存取資料,但在開發應用程式時,將存取權設為「任何已驗證的使用者」可能很有用。

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    match /some_collection/{document} {
      allow read, write: if request.auth != null;
    }
  }
}

Realtime Database

{
  "rules": {
    "some_path": {
      ".read": "auth.uid !== null",
      ".write": "auth.uid !== null"
    }
  }
}

Cloud Storage

service firebase.storage {
  match /b/{bucket}/o {
    match /some_folder/{fileName} {
      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}/{document} {
      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>/file.txt"
    match /user/{userId}/{fileName} {
      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>/file.txt"
    match /user/{userId}/{fileName} {
      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 administrator 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 use
        ".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;
  }
}