管理及部署 Firebase 安全性規則

Firebase 提供多種工具,方便您管理Rules 使用相同後端 Firebase 的情況 Security Rules Management API。

無論叫用工具時使用的工具為何,管理 API 都會:

  • 擷取規則「來源」:一組規則,通常是包含 Firebase Security Rules 陳述式。
  • 將擷取的來源儲存為不可變更的規則
  • 追蹤版本中每個規則集的部署情況。Firebase 安全性 啟用規則的服務會查詢專案的版本,藉此評估各項要求 並取得安全資源
  • 可讓您執行規則集的語法和語意測試

使用 Firebase CLI

透過 Firebase CLI,您可以 上傳本機的來源並部署版本。CLI 的 Firebase Local Emulator Suite 可讓您對來源執行完整本機測試。

使用 CLI 即可在版本管控之下,控管規則 應用程式程式碼及部署規則。

產生設定檔

使用 Firebase CLI 設定 Firebase 專案時, 專案目錄中的 .rules 設定檔。使用下列參數 指令開始設定 Firebase 專案:

Cloud Firestore

// Set up Firestore in your project directory, creates a .rules file
firebase init firestore

Realtime Database

// Set up Realtime Database in your project directory, creates a .rules file
firebase init database

Cloud Storage

// Set up Storage in your project directory, creates a .rules file
firebase init storage

編輯及更新規則

直接在 .rules 設定檔中編輯規則來源。

確保您在 Firebase CLI 中所做的任何編輯均反映在 Firebase 控制台,或持續使用 Firebase 控制台或 Firebase CLI。否則,您可能會覆寫 Firebase 控制台中所做的變更。

測試更新

Local Emulator Suite 提供所有已啟用安全性規則的模擬器 很少直接解答該如何打造產品每個模擬器的安全性規則引擎會同時執行語法 和語意評估,因此超過了語法測試 Security Rules Management API 提供。

如果您正在使用 CLI,是適合 Firebase Security Rules 的全方位工具。 進行測試。使用 Local Emulator Suite 測試更新結果 確認應用程式的 Rules 是否表現出

部署更新

更新及測試 Rules 後,請將原始碼部署至 。

若是 Cloud Firestore Security Rules,請將 .rules 檔案與您的預設值和 查看並更新 firebase.json 檔案

您可以使用下列指令自行選擇部署 Rules,或是 並在正常的部署程序中進行部署。

Cloud Firestore

// Deploy rules for all databases configured in your firebase.json
firebase deploy --only firestore:rules
// Deploy rules for the specified database configured in your firebase.json firebase deploy --only firestore:<databaseId>

Realtime Database

// Deploy your .rules file
firebase deploy --only database

Cloud Storage

// Deploy your .rules file
firebase deploy --only storage

使用 Firebase 控制台

您也可以編輯 Rules來源,並將其部署為版本Firebase 控制台。語法測試會在 Firebase 控制台 UI 和語意測試使用 Rules遊樂場。

編輯及更新規則

  1. 開啟 Firebase 控制台,然後選取所需專案。
  2. 然後選取「Realtime Database、「Cloud Firestore或「儲存空間」: 產品導覽頁面,然後點選「規則」,前往 Rules編輯者。
  3. 直接在編輯器中編輯規則。
,瞭解如何調查及移除這項存取權。

測試更新

除了在編輯器 UI 中測試語法外,您還可以測試語意 Rules 行為 (使用專案的資料庫和儲存空間資源時) 直接透過 Firebase 控制台使用 Rules 遊樂場。開啟「Rules Playground」。 修改設定,然後按一下「Run」Rules 查看編輯器頂端是否有確認訊息。

部署更新

確認更新內容正確無誤後,請按一下「發布」

使用 Admin SDK

您可以使用 Node.js 適用的 Admin SDK 「規則」。透過這個程式輔助存取權,您可以:

  • 導入自訂工具、指令碼、資訊主頁和 CI/CD 管道,以便管理規則。
  • 管理多項 Firebase 專案的規則更輕鬆。

以程式輔助方式更新規則時,請務必避免 無意間變更應用程式的存取權控制項。撰寫 Admin SDK 程式碼 優先考量安全性,特別是在更新或更新規則時。

另外也請注意,Firebase Security Rules 版本 才會完全傳播使用 Admin SDK 部署時 不過,請務必避免應用程式立即仰賴的競爭狀況 處理尚未完成部署作業的規則如果用途 經常更新存取權控管規則,考慮使用 Cloud Firestore 的解決方案。 這個架構專為頻繁更新而設計,可降低競爭狀況。

此外,也請注意下列限制:

  • 規則序列化時,必須小於 256 KiB (採用 UTF-8 編碼的文字)。
  • 每項專案的已部署規則集最多可達 2500 個。達到上限後 達到,您必須先刪除一些舊規則集,才能建立新規則集。

建立及部署 Cloud StorageCloud Firestore 規則集

使用 Admin SDK 管理安全性規則的一般工作流程包括 三個獨立步驟:

  1. 建立規則檔案來源 (選用)
  2. 建立規則集
  3. 發布或部署新的規則集

SDK 提供了一種方法,能將這些步驟結合成單一的 API 呼叫, 「Cloud Storage」和「Cloud Firestore」安全性規則。例如:

    const source = `service cloud.firestore {
      match /databases/{database}/documents {
        match /carts/{cartID} {
          allow create: if request.auth != null && request.auth.uid == request.resource.data.ownerUID;
          allow read, update, delete: if request.auth != null && request.auth.uid == resource.data.ownerUID;
        }
      }
    }`;
    // Alternatively, load rules from a file
    // const fs = require('fs');
    // const source = fs.readFileSync('path/to/firestore.rules', 'utf8');

    await admin.securityRules().releaseFirestoreRulesetFromSource(source);

這個模式也適用於具備 releaseFirestoreRulesetFromSource()Cloud Storage 規則。

您也可以建立規則檔案做為記憶體內物件,建立 並個別部署規則集,以便進一步控制這些事件。 例如:

    const rf = admin.securityRules().createRulesFileFromSource('firestore.rules', source);
    const rs = await admin.securityRules().createRuleset(rf);
    await admin.securityRules().releaseFirestoreRuleset(rs);

更新 Realtime Database 項規則集

如要使用 Admin SDK 更新 Realtime Database 規則集,請使用 getRules()admin.databasesetRules() 方法。您可以擷取 JSON 格式的規則集 格式,或是以包含註解的字串表示。

如要更新規則集,請按照下列步驟操作:

    const source = `{
      "rules": {
        "scores": {
          ".indexOn": "score",
          "$uid": {
            ".read": "$uid == auth.uid",
            ".write": "$uid == auth.uid"
          }
        }
      }
    }`;
    await admin.database().setRules(source);

管理規則集

Admin SDK 可讓您列出所有現有規則,以便管理大型規則集 admin.securityRules().listRulesetMetadata。例如:

    const allRulesets = [];
    let pageToken = null;
    while (true) {
      const result = await admin.securityRules().listRulesetMetadata(pageToken: pageToken);
      allRulesets.push(...result.rulesets);
      pageToken = result.nextPageToken;
      if (!pageToken) {
        break;
      }
    }

對於長期達到 2500 項規則集限制的非常大型部署作業 建立邏輯,在固定的週期中刪除最舊規則。舉例來說 刪除部署超過 30 天的所有規則集:

    const thirtyDays = new Date(Date.now() - THIRTY_DAYS_IN_MILLIS);
    const promises = [];
    allRulesets.forEach((rs) => {
      if (new Date(rs.createTime) < thirtyDays) {
        promises.push(admin.securityRules().deleteRuleset(rs.name));
      }
    });
    await Promise.all(promises);
    console.log(`Deleted ${promises.length} rulesets.`);

使用 REST API。

上述工具適用於各種工作流程,包括 Firebase Security Rules 管理專案中多個 Cloud Firestore 資料庫, 但建議您使用 Management API 來管理及部署 Firebase Security Rules。 Management API 給您最大的彈性。

此外,也請注意下列限制:

  • 規則序列化時,必須小於 256 KiB (採用 UTF-8 編碼的文字)。
  • 每項專案的已部署規則集最多可達 2500 個。達到上限後 達到,您必須先刪除一些舊規則集,才能建立新規則集。

使用 REST 建立及部署 Cloud FirestoreCloud Storage 規則集

本節中的範例使用的是 Firestore Rules (但適用於 Cloud Storage Rules

這些範例也使用 cURL 發出 API 呼叫。設定及通過步驟 省略驗證權杖。您可以使用 APIs Explorer 已與 參考文件

使用 Management API 建立及部署規則集的一般步驟如下:

  1. 建立規則檔案來源
  2. 建立規則集
  3. 發布 (部署) 新規則集。

建立來源

假設您正在處理 secure_commerce Firebase 專案 ,將鎖定 Cloud Firestore Rules 部署至您的資料庫 名為 east_store 的專案

您可以在 firestore.rules 中實作這些規則 檔案。

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

建立規則集

現在,請為這個檔案產生 Base64 編碼指紋。接著,您可以使用 原始碼,以填入建立規則集所需的酬載 projects.rulesets.create REST 呼叫。接著,使用 cat 指令插入 將 firestore.rules 的內容放入 REST 酬載中。

如要進行追蹤,請將 attachment_point 設為 east_store,以將這個資料庫與資料庫建立關聯。east_store

curl -X POST -d '{
  "source": {
    "files": [
      {
        "content": "' $(cat storage.rules) '",
        "name": "firestore.rules",
        "fingerprint": <sha fingerprint>
      },
    "attachment_point": "firestore.googleapis.com/databases/east_store"
    ]
  }
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/rulesets'

API 會傳回驗證回應和規則集名稱,例如 projects/secure_commerce/rulesets/uuid123

釋出 (部署) 規則集

如果規則集有效,最後一個步驟就是在名為 版本。

curl -X POST -d '{
  "name": "projects/secure_commerce/releases/cloud.firestore/east_store"  ,
  "rulesetName": "projects/secure_commerce/rulesets/uuid123"
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/releases'

請注意,Firebase Security Rules 版本需要幾分鐘才會完全完成 傳遞作業使用 Management REST API 進行部署時,請務必避免競爭 應用程式立即依賴非部署規則的規則 尚未完成

使用 REST 更新 Realtime Database 項規則集

Realtime Database 提供用於管理 Rules 的專屬 REST 介面。詳情請見 透過 REST 管理 Firebase Realtime Database Rules

使用 REST 管理規則集

為了協助管理大型規則部署作業,除了 建立規則集和發布版本,管理 API 提供以下方法:

  • 列出、取得及刪除規則集
  • 列出、取得及刪除規則版本

對於長期達到 2500 項規則集限制的非常大型部署作業 建立邏輯,在固定的週期中刪除最舊規則。舉例來說 刪除部署超過 30 天的「所有」規則集,您就能呼叫 projects.rulesets.list 方法,剖析以下項目中 Ruleset 物件的 JSON 清單: createTime金鑰,然後呼叫 project.rulesets.delete ruleset_id 的對應規則集。

使用 REST 測試更新

最後,運用 Management API 執行語法和語意測試 實際工作環境中的 Cloud FirestoreCloud Storage 項資源 Google Cloud 的 Resource Manager 工具 經特別設計,能以程式輔助方式協助您管理專案

使用這個 API 元件進行測試包括:

  1. 定義 TestSuite JSON 物件來代表一組 TestCase 物件
  2. 提交 TestSuite
  3. 剖析傳回的 TestResult 物件

我們如使用單一 TestCase 定義 TestSuite 物件, testcase.json 檔案。在此範例中,我們傳遞 Rules 將語言來源嵌入 REST 酬載,以及要執行的測試套件 查看所有規則我們會指定規則評估預期,以及用戶端 要求測試規則集。您也可以指定 測試報告是將值設為「FULL」表示含有「 」 報表應包含 Rules 個語言運算式,包括 與要求不相符的運算式。

 {
  "source":
  {
    "files":
    [
      {
        "name": "firestore.rules",
        "content": "service cloud.firestore {
          match /databases/{database}/documents {
            match /users/{userId}{
              allow read: if (request.auth.uid == userId);
            }
            function doc(subpath) {
              return get(/databases/$(database)/documents/$(subpath)).data;
            }
            function isAccountOwner(accountId) {
              return request.auth.uid == accountId 
                  || doc(/users/$(request.auth.uid)).accountId == accountId;
            }
            match /licenses/{accountId} {
              allow read: if isAccountOwner(accountId);
            }
          }
        }"
      }
    ]
  },
  "testSuite":
  {
    "testCases":
    [
      {
        "expectation": "ALLOW",
        "request": {
           "auth": {"uid": "123"},
           "path": "/databases/(default)/documents/licenses/abcd",
           "method": "get"},
        "functionMocks": [
            {
            "function": "get",
            "args": [{"exact_value": "/databases/(default)/documents/users/123"}],
            "result": {"value": {"data": {"accountId": "abcd"}}}
            }
          ]
      }
    ]
  }
}

然後,我們可以提交這個 TestSuite 來進行使用 projects.test 評估 方法。

curl -X POST -d '{
    ' $(cat testcase.json) '
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/rulesets/uuid123:test'

傳回的 TestReport (包含測試成功/失敗狀態,清單 偵錯訊息、造訪過的規則運算式清單及相關評估報告) 會確認狀態「成功」已正確允許存取。

管理跨服務「Cloud Storage Security Rules」的權限

如果您建立的Cloud Storage Security Rules會使用 Cloud Firestore 文件內容 評估安全性條件 Firebase 控制台或 Firebase CLI 會提示您啟用 來連結這兩項產品

如果決定停用這類跨服務安全防護機制:

  1. 停用功能前,請先編輯規則,移除所有 使用 Rules 函式存取 Cloud Firestore 的陳述式。 否則,停用功能後,Rules的評估作業 造成 Storage 要求失敗

  2. 使用 Google Cloud 控制台中的「IAM」頁面刪除 Firebase Rules Firestore 服務代理角色,遵循 撤銷角色

系統會在您下次儲存時,提示您重新啟用這項功能 Firebase CLI 或 Firebase 控制台的跨服務規則。