Catch up on highlights from Firebase at Google I/O 2023. Learn more

基本安全規則

Firebase 安全規則允許您控制對存儲數據的訪問。靈活的規則語法意味著您可以創建匹配任何內容的規則,從對整個數據庫的所有寫入到對特定文檔的操作。

本指南介紹了您在設置應用程序和保護數據時可能想要實現的一些更基本的用例。但是,在開始編寫規則之前,您可能想要了解有關編寫規則所用的語言及其行為的更多信息。

要訪問和更新您的規則,請按照管理和部署 Firebase 安全規則中概述的步驟進行操作。

默認規則:鎖定模式

當您在 Firebase 控制台中創建數據庫或存儲實例時,您可以選擇 Firebase 安全規則是限制對您的數據的訪問(鎖定模式)還是允許任何人訪問(測試模式)。在 Cloud Firestore 和 Realtime Database 中,鎖定模式的默認規則拒絕所有用戶的訪問。在 Cloud Storage 中,只有經過身份驗證的用戶才能訪問存儲桶。

雲Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if false;
    }
  }
}

實時數據庫

{
  "rules": {
    ".read": false,
    ".write": false
  }
}

雲儲存

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
  }
}

開發環境規則

當您開發應用程序時,您可能希望相對開放或不受限制地訪問您的數據。請務必在將應用程序部署到生產環境之前更新您的規則。另請記住,如果您部署了應用程序,它就可以公開訪問 - 即使您尚未啟動它。

請記住,Firebase 允許客戶端直接訪問您的數據,而 Firebase 安全規則是阻止惡意用戶訪問的唯一保障措施。與產品邏輯分開定義規則有很多優點:客戶端不負責強制執行安全性,有缺陷的實現不會損害您的數據,最重要的是,您不依賴中間服務器來保護數據免受外界侵害。

所有經過身份驗證的用戶

雖然我們不建議讓任何已登錄的用戶都可以訪問您的數據,但在開發應用程序時設置對任何經過身份驗證的用戶的訪問權限可能會很有用。

雲Firestore

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

實時數據庫

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

雲儲存

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
  }
}

生產就緒規則

當您準備部署應用程序時,請確保您的數據受到保護,並且訪問權限已正確授予您的用戶。利用身份驗證來設置基於用戶的訪問,並直接從數據庫讀取以設置基於數據的訪問。

考慮在構建數據時編寫規則,因為設置規則的方式會影響如何限制對不同路徑上的數據的訪問。

僅限內容所有者訪問

這些規則僅限制經過身份驗證的內容所有者的訪問。數據只能由一個用戶讀寫,並且數據路徑包含用戶的ID。

當此規則起作用時:如果數據由用戶隔離,則此規則效果很好 - 如果需要訪問數據的唯一用戶是創建數據的同一用戶。

當此規則不起作用時:當多個用戶需要寫入或讀取相同數據時,此規則集不起作用 - 用戶將覆蓋數據或無法訪問他們創建的數據。

要設置此規則:創建一條規則,確認請求讀取或寫入數據的訪問權限的用戶是擁有該數據的用戶。

雲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
    }
  }
}

實時數據庫

{
  "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"
      }
    }
  }
}

雲儲存

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

公共和私人混合訪問

此規則允許任何人讀取數據集,但僅限經過身份驗證的內容所有者在給定路徑上創建或修改數據的能力。

當此規則有效時:此規則適用於需要公開可讀元素但需要限制對這些元素所有者的編輯訪問權限的應用程序。例如,聊天應用程序或博客。

當此規則不起作用時:與僅限內容所有者規則一樣,當多個用戶需要編輯相同數據時,此規則集不起作用。用戶最終將覆蓋彼此的數據。

要設置此規則:創建一條規則,啟用所有用戶(或所有經過身份驗證的用戶)的讀取訪問權限,並確認寫入數據的用戶是所有者。

雲Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow public read access, but only content owners can write
    match /some_collection/{document} {
      allow read: if true
      allow create: if request.auth.uid == request.resource.data.author_uid;
      allow update, delete: if request.auth.uid == resource.data.author_uid;
    }
  }
}

實時數據庫

{
// 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"
      }
    }
  }
}

雲儲存

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 安全規則根據數據庫或文件元數據中的數據檢查請求,以確認或拒絕訪問。

當此規則起作用時:如果您要向用戶分配角色,則此規則可以輕鬆地根據角色或特定用戶組限制訪問。例如,如果您要存儲成績,則可以為“學生”組(僅讀取其內容)、“教師”組(讀取和寫入其主題)和“校長”組(讀取其內容)分配不同的訪問級別。所有內容)。

當此規則不起作用時:在實時數據庫和 Cloud Storage 中,您的規則無法利用 Cloud Firestore 規則可以合併的get()方法。因此,您必須構建數據庫或文件元數據以反映您在規則中使用的屬性。

要設置此規則,請執行以下操作:在 Cloud Firestore 中,在用戶的文檔中包含一個您可以讀取的字段,然後構建您的規則以讀取該字段並有條件地授予訪問權限。在實時數據庫中,創建一個數據路徑來定義應用程序的用戶並授予他們在子節點中的角色。

您還可以在身份驗證中設置自定義聲明,然後從任何 Firebase 安全規則中的auth.token變量檢索該信息。

數據定義的屬性和角色

這些規則僅適用於 Cloud Firestore 和實時數據庫。

雲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"
   }
  }
}

實時數據庫

{
  "rules": {
    "some_path": {
      "${subpath}": {
        //
        ".write": "root.child('users').child(auth.uid).child('role').val() === 'admin'",
        ".read": true
      }
    }
  }
}

自定義聲明屬性和角色

要實施這些規則,請在 Firebase 身份驗證中設置自定義聲明,然後利用規則中的聲明。

雲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";
   }
  }
}

實時數據庫

{
  "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"
      }
    }
  }
}

雲儲存

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

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

實時數據庫

{
  "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
      }
    }
  }
}

雲儲存

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