管道作業的安全性規則
管道作業規則可讓您比對現有規則引擎的篩選功能。雖然管道作業提供豐富的功能,但規則引擎僅限於辨識簡單的篩選器,以確保查詢可滿足需求和安全性。
版本和模式需求
本文適用於原生模式的 Firestore Enterprise 版。
支援的篩選運算式
查詢必須使用標準比較運算子與常數,才能受到規則限制。規則引擎可辨識下列篩選器類型:
- 相等和不相等:
eq、neq。 - 比較:
gt、gte、lt、lte。 - 會員資格:
in、arrayContains。
例如:
where(eq("foo", 2))where(lt("foo", 2))documents("/user/1", "/user/2").where(...)
要求屬性
您可以繼續使用 request 物件驗證驗證和查詢內容,但管道不支援標準查詢中的部分屬性。
支援的屬性
新引擎仍支援下列屬性:
request.auth:存取使用者 UID 和權杖資料。request.method:識別作業 (例如get、list)。request.path:存取資源的路徑。request.time:要求的伺服器端時間戳記。
不支援的屬性
由於在多級式查詢中判斷這些值相當複雜,因此管道規則檢查不支援 request.query 屬性,例如 limit、offset 和 orderBy。
管道階段處理和權限
管道階段有許多種,分別對應安全性規則中的特定精細作業:
allow list權限:由collection()、collectionGroup()和database()階段觸發。allow get權限:由documents()階段觸發,處理方式與批次get作業類似。allow create權限:建立新文件時,由insert()階段和upsert()階段觸發。allow update權限:由update()階段觸發,更新現有文件時則由upsert()階段觸發。allow delete權限:由delete()個階段觸發。allow write權限:適用於所有 DML 作業 (insert()、update()、upsert()和delete())。- 欄位修改階段:規則只會對儲存的資料執行,不會對衍生值執行。如果管道包含修改欄位的階段 (例如
AddFields、ReplaceWith、Select),規則引擎會在遇到該階段後停止套用篩選器限制。 - 常值階段:
literals()階段不會從資料庫讀取資料,但可能會產生費用。為防範濫用情形,必須與可由規則驗證的其他階段 (例如collection()) 搭配使用。
data manipulation language (DML) 階段和安全性規則
執行資料操縱語言 (DML) 階段 (insert()、update()、upsert() 和 delete()) 時,安全性規則評估權限的方式與讀取查詢不同:
- 逐一評估文件規則:讀取管道需要預先提供篩選運算式,以便在規劃階段限制查詢,但 DML 作業會針對每項文件異動評估安全性規則。
- 規則變數:
request.resource:包含insert()、update()和upsert()作業的建議文件資料。resource:包含修改前儲存在資料庫中的目前文件資料 (適用於現有文件的update()、delete()和upsert())。
DML 的系統限制和執行行為
使用安全性規則執行 DML 作業時,請注意下列系統限制和執行行為:
get() 和 exists() 的查詢次數上限為 20 次
Firebase 安全性規則允許在整個要求中最多執行 20 次文件查詢 (get() 或 exists())。
如果 DML 管道在明確交易外執行,文件會分批處理。由於每個批次都會在自己的交易中執行,且文件可能會在批次之間同時修改,因此系統會針對每個寫入批次重新評估安全性規則和文件查詢。
即使安全性規則是針對單一靜態文件進行評估,例如檢查使用者是否為管理員:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /posts/{postId} {
allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.isAdmin == true;
}
}
}
每批寫入的文件都會執行查詢。因此,在寫入所有可能的文件後,要求達到 20 次查詢限制,管道失敗並顯示 PERMISSION_DENIED 錯誤。此外,每個寫入批次執行的每次查詢,都會產生各自的讀取費用。
部分成功和PERMISSION_DENIED
在交易外執行時,DML 作業會依序批次提交寫入作業。如果批次作業失敗 (可能是因為文件不符合規則條件,或超過 20 次查詢限制),管道就會停止並傳回 PERMISSION_DENIED 錯誤。
不過,已提交的批次不會復原。資料庫會維持在部分更新狀態。由於用戶端收到的錯誤訊息不含已修改文件的清單,因此您必須查詢資料,檢查哪些寫入作業成功。
使用 Cloud 稽核記錄診斷規則失敗
基於安全考量,用戶端 PERMISSION_DENIED 錯誤不會揭露失敗的安全規則條件,或是否達到 20 次查詢限制。
如要診斷規則評估失敗的原因,專案管理員可以在 Google Cloud 控制台 (依序前往「Firestore」 >「Monitoring」或「Logs Explorer」) 查看 Cloud 稽核記錄,檢視詳細的EvaluationError項目。