Firebase 為您提供了多種工具來管理您的規則,每一種都在特定情況下很有用,並且每一種都使用相同的後端 Firebase 安全規則管理 API。
無論使用哪個工具調用它,管理 API:
- 提取規則源:一組規則,通常是包含 Firebase 安全規則語句的代碼文件。
- 將攝取的源存儲為不可變的規則集。
- 跟踪發布中每個規則集的部署。啟用 Firebase 安全規則的服務會查找項目的發布,以評估對安全資源的每個請求。
- 提供運行規則集的句法和語義測試的能力。
使用 Firebase CLI
使用Firebase CLI ,您可以上傳本地資源並部署發布。 CLI 的 Firebase Local Emulator Suite 允許您對源執行完整的本地測試。
使用 CLI 允許您使用應用程序代碼將規則置於版本控制之下,並將規則部署為現有部署過程的一部分。
生成配置文件
使用 Firebase CLI 配置 Firebase 項目時,您會在項目目錄中創建一個.rules
配置文件。使用以下命令開始配置您的 Firebase 項目:
雲端 Firestore
// Set up Firestore in your project directory, creates a .rules file firebase init firestore
實時數據庫
// Set up Realtime Database in your project directory, creates a .rules file firebase init database
雲儲存
// 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 為所有支持安全規則的產品提供模擬器。每個模擬器的安全規則引擎執行規則的句法和語義評估,因此超過了安全規則管理 API 提供的句法測試。
如果您使用 CLI,該套件是 Firebase 安全規則測試的絕佳工具。使用Local Emulator Suite在本地測試您的更新並確認您的應用程序規則表現出您想要的行為。
部署您的更新
更新並測試規則後,將源代碼部署到生產環境中。使用以下命令有選擇地單獨部署您的規則,或將它們部署為正常部署過程的一部分。
雲端 Firestore
// Deploy your .rules file firebase deploy --only firestore:rules
實時數據庫
// Deploy your .rules file firebase deploy --only database
雲儲存
// Deploy your .rules file firebase deploy --only storage
使用 Firebase 控制台
您還可以編輯規則源並將它們部署為來自 Firebase 控制台的版本。當您在 Firebase 控制台 UI 中編輯時執行語法測試,並且可以使用 Rules Playground 進行語義測試。
編輯和更新您的規則
- 打開Firebase 控制台並選擇您的項目。
- 然後,從產品導航中選擇Realtime Database 、 Cloud Firestore或Storage ,然後單擊Rules以導航到規則編輯器。
- 直接在編輯器中編輯您的規則。
測試您的更新
除了在編輯器 UI 中測試語法外,您還可以直接在 Firebase 控制台中使用Rules Playground使用項目的數據庫和存儲資源來測試語義規則行為。在規則編輯器中打開規則遊樂場屏幕,修改設置並單擊運行。在編輯器頂部查找確認消息。
部署您的更新
一旦您對您的更新符合預期感到滿意,請點擊發布。
使用管理 SDK
您可以使用 Admin SDK for Node.js規則集。通過這種編程訪問,您可以:
- 實施自定義工具、腳本、儀表板和 CI/CD 管道以管理規則。
- 跨多個 Firebase 項目更輕鬆地管理規則。
以編程方式更新規則時,避免對應用程序的訪問控制進行意外更改非常重要。在編寫 Admin SDK 代碼時,請將安全放在首位,尤其是在更新或部署規則時。
另一件需要牢記的重要事情是,Firebase 安全規則發布需要幾分鐘時間才能完全傳播。使用 Admin SDK 部署規則時,請確保避免您的應用立即依賴部署尚未完成的規則的競爭條件。如果您的用例需要頻繁更新訪問控制規則,請考慮使用 Cloud Firestore 的解決方案,它旨在減少頻繁更新的競爭條件。
另請注意以下限制:
- 序列化時,規則必須小於 256 KiB 的 UTF-8 編碼文本。
- 一個項目總共最多可以部署 2500 個規則集。一旦達到此限制,您必須在創建新規則集之前刪除一些舊規則集。
創建和部署 Cloud Storage 或 Cloud Firestore 規則集
使用 Admin SDK 管理安全規則的典型工作流程可能包括三個獨立的步驟:
- 創建規則文件源(可選)
- 創建規則集
- 發布或部署新規則集
SDK 提供了一種方法,可以將這些步驟合併到針對 Cloud Storage 和 Cloud Firestore 安全規則的單個 API 調用中。例如:
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);
更新實時數據庫規則集
要使用 Admin SDK 更新實時數據庫規則集,請使用admin.database
的getRules()
和setRules()
方法。您可以檢索 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
上述工具非常適合各種工作流程,但您可能希望使用管理 API 本身來管理和部署 Firebase 安全規則。管理 API 為您提供最大的靈活性。
請注意,Firebase 安全規則發布需要幾分鐘時間才能完全傳播。使用管理 REST API 進行部署時,請確保避免應用程序立即依賴部署尚未完成的規則的競爭條件。
另請注意以下限制:
- 序列化時,規則必須小於 256 KiB 的 UTF-8 編碼文本。
- 一個項目總共最多可以部署 2500 個規則集。一旦達到此限制,您必須在創建新規則集之前刪除一些舊規則集。
使用 REST 創建和部署 Cloud Storage 或 Cloud Firestore 規則集
本部分中的示例使用存儲規則,但它們也適用於 Cloud Firestore 規則。
這些示例還使用 cURL 進行 API 調用。省略了設置和傳遞身份驗證令牌的步驟。您可以使用與參考文檔集成的 API Explorer 試驗此 API。
使用管理 API 創建和部署規則集的典型步驟是:
- 創建規則文件源
- 創建規則集
- 發布(部署)新規則集
假設您正在處理secure_commerce
Firebase 項目並希望部署鎖定的雲存儲規則。您可以在storage.rules
文件中實施這些規則。
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if false;
}
}
}
現在,為這個文件生成一個 base64 編碼的指紋。然後,您可以使用此文件中的源來填充通過projects.rulesets.create
REST 調用創建規則集所需的負載。在這裡,我們使用cat
命令將storage.rules
的內容插入到 REST 負載中。
curl -X POST -d '{
"source": {
{
"files": [
{
"content": "' $(cat storage.rules) '",
"name": "storage.rules",
"fingerprint": <sha fingerprint>
}
]
}
}
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/rulesets'
API 返回驗證響應和規則集名稱,例如projects/secure_commerce/rulesets/uuid123
。如果規則集有效,最後一步是在命名版本中部署新規則集。
curl -X POST -d '{
"name": "projects/secure_commerce/releases/prod/v23 " ,
"rulesetName": "projects/secure_commerce/rulesets/uuid123",
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/releases'
使用 REST 更新實時數據庫規則集
實時數據庫提供自己的 REST 接口來管理規則。請參閱通過 REST 管理 Firebase 實時數據庫規則。
使用 REST 管理規則集
為了幫助管理大型規則部署,除了用於創建規則集和發布的 REST 方法之外,管理 API 還提供了以下方法:
- 列出、獲取和刪除規則集
- 列出、獲取和刪除規則發布
對於隨著時間的推移達到 2500 個規則集限制的超大型部署,您可以創建邏輯以按固定時間週期刪除最舊的規則。例如,要刪除部署時間超過 30 天的所有規則集,可以調用projects.rulesets.list
方法,在其createTime
鍵上解析Ruleset
對象的 JSON 列表,然後通過ruleset_id
在相應的規則集上調用project.rulesets.delete
.
使用 REST 測試您的更新
最後,管理 API 允許您對生產項目中的 Cloud Firestore 和 Cloud Storage 資源運行語法和語義測試。
使用此 API 組件進行的測試包括:
- 定義一個
TestSuite
JSON 對象來表示一組TestCase
對象 - 提交
TestSuite
- 解析返回的
TestResult
對象
讓我們在testcase.json
文件中定義一個帶有單個TestCase
TestSuite
對象。在此示例中,我們傳遞與 REST 有效負載內聯的規則語言源,以及要在這些規則上運行的測試套件。我們指定規則評估期望,以及要測試規則集的客戶端請求。您還可以指定測試報告的完整程度,使用值“FULL”指示所有規則語言表達式的結果應包含在報告中,包括與請求不匹配的表達式。
{ "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"}}} } ] } ] } }
然後我們可以使用projects.test
方法提交這個TestSuite
進行評估。
curl -X POST -d '{
' $(cat testcase.json) '
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/rulesets/uuid123:test'
返回的TestReport
(包含測試 SUCCESS/FAILURE 狀態、調試消息列表、訪問的規則表達式列表及其評估報告)將以 SUCCESS 狀態確認訪問被正確允許。
管理跨服務雲存儲安全規則的權限
如果您創建使用Cloud Firestore 文檔內容評估安全條件的Cloud Storage 安全規則,系統會在 Firebase 控制台或 Firebase CLI 中提示您啟用連接這兩個產品的權限。
如果您決定禁用此類跨服務安全性:
首先,在禁用該功能之前,編輯您的規則,刪除所有使用規則函數訪問 Cloud Firestore 的語句。否則,禁用該功能後,規則評估將導致您的存儲請求失敗。
使用 Google Cloud Console 中的IAM頁面按照Cloud guide for revoking roles刪除“Firebase Rules Firestore Service Agent”角色。
下次您從 Firebase CLI 或 Firebase 控制台保存跨服務規則時,系統將提示您重新啟用該功能。