กฎความปลอดภัยสำหรับการดำเนินการในไปป์ไลน์

แม้ว่าการดำเนินการไปป์ไลน์จะมีฟีเจอร์มากมาย แต่เครื่องมือจัดการกฎจะจำกัดการรับรู้ตัวกรองการเปรียบเทียบ (เช่น >) และตัวกรองเชิงตรรกะ (เช่น or) เพื่อให้มั่นใจถึงความพึงพอใจของข้อจำกัดและความปลอดภัย

นิพจน์ตัวกรองที่รองรับ

หากต้องการให้การดำเนินการของไปป์ไลน์อยู่ภายในขอบเขตที่กำหนดโดยกฎ คุณต้องใช้ ตัวดำเนินการเชิงตรรกะและการเปรียบเทียบกับค่าคงที่ เครื่องมือจัดการกฎจะรู้จักตัวกรองประเภทต่อไปนี้

  • การเปรียบเทียบ: eq, neq, gt, gte, lt, lte, in, arrayContains
  • ตรรกะ: and, or

ตัวอย่างเช่น

  • 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 permissions: เรียกใช้โดยขั้นตอน 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สเตจ เกิดขึ้นก่อนการกรองเอกสารที่ visibility เป็น public

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();