管道作業的安全規則

雖然 Pipeline 作業提供豐富的功能,但規則引擎只能辨識比較 (例如 >) 和邏輯 (例如 or) 篩選器,確保約束條件可滿足且安全無虞。

支援的篩選運算式

如要將管道作業限制在規則設定的範圍內,管道作業必須使用邏輯和比較運算子來比較常數。規則引擎可辨識下列篩選器類型:

  • 比較:eqneqgtgteltlteinarrayContains
  • 邏輯檢視表:andor

例如:

  • where(eq("foo", 2))
  • where(lt("foo", 2))
  • documents("/user/1", "/user/2").where(...)

要求屬性

您仍可使用 request 物件驗證驗證和查詢內容,但管道作業不支援標準查詢中的部分屬性。

支援的屬性

新引擎仍支援下列屬性:

  • request.auth:存取使用者 UID 和權杖資料。
  • request.method:識別作業 (例如 getlist)。
  • request.path:正在存取的資源路徑。
  • request.time:要求的伺服器端時間戳記。

不支援的屬性

由於在多級式查詢中判斷這些值相當複雜,因此系統不支援對管道作業規則檢查使用 request.query 屬性,例如 limitoffsetorderBy

管道階段處理方式和權限

管道的不同階段會對應至安全規則中的特定細微作業:

  • allow list 權限:由 collection()collectionGroup()database() 階段觸發。
  • allow get 權限:由 documents() 階段觸發,處理方式與批次 get 作業類似。
  • 常值階段:literals() 階段不會從資料庫讀取資料,但可能會產生費用。為防範濫用情形,這個階段必須與可透過規則驗證的其他階段 (例如 collection()) 配對。

欄位修改階段

規則只會對儲存的資料生效,不會對衍生值生效。如果管道包含會修改欄位的階段 (例如 add_fields(...)replace_with(...)select(...)remove_fields(...)),規則引擎會在遇到該階段後停止套用篩選條件限制。為確保規則正常運作,請將篩選器階段 (即 where) 放在任何可修改原始儲存文件的階段之前。

舉例來說,請參考下列安全性規則:

match /databases/{database}/documents {
  match /cities/{city} {
    // Allow the user to read data if the document has the 'visibility'
    // field set to 'public'
    allow read: if resource.data.visibility == 'public';
  }
}

已拒絕:這項規則會拒絕下列管道,因為 addFields 階段發生在篩選文件之前,而 visibilitypublic

const results = await db.pipeline()
  .collection("/cities")
  // Filters after a modification stage are ignored by Rules.
  .addFields(constant(1000).as("population"))
  .where(eq(field("visibility"), constant("public")))
  .execute();

允許:這項規則允許下列管道,因為 where(eq(field("visibility"), constant("public"))) 階段發生在任何修改階段之前:

const results = await db.pipeline()
  .collection("/cities")
  .where(eq(field("visibility"), constant("public")))
  .addFields(constant(1000).as("population"))
  .execute();