了解 2023 年 Google I/O 大会上介绍的 Firebase 亮点。了解详情

基本安全規則

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

本指南描述了您在設置應用程序和保護數據時可能希望實施的一些更基本的用例。然而,在您開始編寫規則之前,您可能希望了解更多有關規則編寫語言及其行為的信息。

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

默認規則:鎖定模式

當您在 Firebase 控制台中創建數據庫或存儲實例時,您可以選擇您的 Firebase 安全規則是限制對您的數據的訪問(鎖定模式)還是允許任何人訪問(測試模式)。在 Cloud Firestore 和實時數據庫中,鎖定模式的默認規則拒絕所有用戶訪問。在 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;
  }
}