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,Suite 是測試 Firebase Security Rules 的絕佳工具。使用 Local Emulator Suite 在本機測試更新,並確認應用程式的 Rules 是否顯示您想要的行為。
部署更新
更新及測試 Rules 後,請將來源部署至實際環境。
針對 Cloud Firestore Security Rules,請查看並更新 firebase.json
檔案,將 .rules
檔案與預設和其他已命名的資料庫建立關聯。
請使用下列指令,選擇性地部署 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 控制台
您也可以在 Firebase 控制台中編輯 Rules 來源,並將其部署為版本。您在 Firebase 主控台 UI 中編輯時,系統會執行語法測試,並可使用 Rules Playground 進行語意測試。
編輯及更新規則
- 開啟 Firebase 控制台,然後選取所需專案。
- 接著在產品導覽中選取「Realtime Database」、「Cloud Firestore」或「儲存空間」,然後按一下「規則」前往 Rules 編輯器。
- 直接在編輯器中編輯規則。
測試更新
除了在編輯器 UI 中測試語法之外,您也可以使用 Rules Playground,直接在 Firebase 主控台中使用專案的資料庫和儲存空間資源,測試語意 Rules 行為。在 Rules 編輯器中開啟「Rules Playground」畫面,修改設定,然後按一下「Run」。請留意編輯器頂端的確認訊息。
部署更新
確認更新內容符合預期後,請按一下「發布」。
使用 Admin SDK
您可以使用 Admin SDK 為 Node.js rulesets。有了這項程式輔助存取權,您可以:
- 導入自訂工具、指令碼、儀表板和 CI/CD 管道,以便管理規則。
- 更輕鬆地管理多個 Firebase 專案的規則。
以程式輔助方式更新規則時,請務必避免對應用程式的存取權控管進行非預期變更。請在編寫 Admin SDK 程式碼時,以安全性為首要考量,尤其是在更新或部署規則時。
請注意,Firebase Security Rules 版本需要幾分鐘的時間才能完全發布。使用 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);
這個模式也適用於 Cloud Storage 規則與 releaseFirestoreRulesetFromSource()
。
或者,您也可以將規則檔案建立為記憶體內物件、建立規則集,然後分別部署規則集,以便更精確地控管這些事件。例如:
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 規則集,請使用 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。
上述工具非常適合各種工作流程,包括專案中多個 Cloud Firestore 資料庫的 Firebase Security Rules 管理,但您可能會想使用管理 API 本身來管理及部署 Firebase Security Rules。管理 API 可提供最大的彈性。
此外,也請注意下列限制:
- 規則序列化時,必須小於 256 KiB (採用 UTF-8 編碼的文字)。
- 一個專案最多可部署 2500 個規則集。達到此上限後,您必須先刪除一些舊規則集,才能建立新規則集。
使用 REST 建立及部署 Cloud Firestore 或 Cloud Storage 規則集
本節的範例使用 Firestore Rules,但也適用於 Cloud Storage Rules。
這些範例也使用 cURL 發出 API 呼叫。我們會省略設定及傳遞驗證權權杖的步驟。您可以使用與參考文件整合的 API Explorer 來測試這個 API。
使用管理 API 建立及部署規則集的一般步驟如下:
- 建立規則檔案來源
- 建立規則集
- 發布 (部署) 新規則集。
建立來源
假設您正在處理 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 版本需要幾分鐘的時間才能完全發布。使用管理 REST API 進行部署時,請務必避免競合狀況,也就是應用程式立即依賴尚未完成部署的規則。
使用 REST 更新 Realtime Database 規則集
Realtime Database 提供專屬的 REST 介面,用於管理 Rules。請參閱「透過 REST 管理 Firebase Realtime Database Rules」。
使用 REST 管理規則集
為了協助管理大量規則部署作業,除了用於建立規則集和版本的 REST 方法外,管理 API 還提供下列方法:
- 列出、取得及刪除規則集
- 列出、取得及刪除規則版本
如果部署規模龐大,且隨著時間推移而達到 2500 個規則集的上限,您可以建立邏輯,在固定的時間週期內刪除最舊的規則。舉例來說,如要刪除部署超過 30 天的「all」規則集,您可以呼叫 projects.rulesets.list
方法,剖析 Ruleset
物件的 JSON 清單,並根據 createTime
鍵,對相應規則集呼叫 project.rulesets.delete
。ruleset_id
使用 REST 測試更新
最後,管理 API 可讓您在正式專案中對 Cloud Firestore 和 Cloud Storage 資源執行語法和語意測試。
使用這個 API 元件進行測試包括:
- 定義
TestSuite
JSON 物件,用於代表一組TestCase
物件 - 提交
TestSuite
- 剖析傳回的
TestResult
物件
讓我們在 testcase.json
檔案中定義含有單一 TestCase
的 TestSuite
物件。在這個範例中,我們會將 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"}}} } ] } ] } }
接著,我們可以使用 projects.test
方法提交這個 TestSuite
進行評估。
curl -X POST -d '{
' $(cat testcase.json) '
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/rulesets/uuid123:test'
傳回的 TestReport
(包含測試成功/失敗狀態、偵錯訊息清單、已造訪的規則運算式清單及評估報告) 會以 SUCCESS 狀態確認已允許存取。
管理跨服務 Cloud Storage Security Rules 的權限
如果您建立的 Cloud Storage Security Rules 會使用 Cloud Firestore 文件內容來評估安全條件,系統會在 Firebase 控制台或 Firebase CLI 中提示您啟用權限,以便連結這兩項產品。
如果決定停用這類跨服務安全防護機制:
首先,請先編輯規則,移除使用 Rules 函式存取 Cloud Firestore 的所有陳述式。否則,在停用這項功能後,Rules 評估作業會導致您的儲存空間要求失敗。
請按照Cloud 指南中撤銷角色的說明,使用 Google Cloud 控制台的「身分與存取權管理」頁面刪除「Firebase Rules Firestore Service Agent」角色。
下次透過 Firebase CLI 或 Firebase 主控台儲存跨服務規則時,系統會提示您重新啟用這項功能。