Cloud Firestore Security Rules ช่วยให้คุณควบคุมสิทธิ์เข้าถึงเอกสารและคอลเล็กชันในฐานข้อมูลได้ ไวยากรณ์ของกฎที่ยืดหยุ่นช่วยให้คุณสร้างกฎที่ตรงกับทุกอย่างได้ ตั้งแต่การเขียนทั้งหมดไปยังทั้งฐานข้อมูล ไปจนถึงการดำเนินการในเอกสารที่เฉพาะเจาะจง
คู่มือนี้อธิบายไวยากรณ์และโครงสร้างพื้นฐานของกฎความปลอดภัย รวมไวยากรณ์นี้กับเงื่อนไขของกฎความปลอดภัยเพื่อสร้างชุดกฎที่สมบูรณ์
การประกาศเกี่ยวกับบริการและฐานข้อมูล
Cloud Firestore Security Rules ต้องเริ่มต้นด้วยการประกาศต่อไปนี้เสมอ
service cloud.firestore {
// The {database} wildcard allows the rules to reference any database,
// but these rules are only active on databases where they are explicitly deployed.
match /databases/{database}/documents {
// ...
}
}การประกาศ service cloud.firestore จะกำหนดขอบเขตของกฎเป็น
Cloud Firestore ซึ่งป้องกันไม่ให้เกิดความขัดแย้งระหว่าง Cloud Firestore Security Rules กับ
กฎสำหรับผลิตภัณฑ์อื่นๆ เช่น Cloud Storage
match /databases/{database}/documents การประกาศระบุว่ากฎ
ควรตรงกับCloud Firestore ฐานข้อมูลใดก็ได้ในโปรเจ็กต์ แม้ว่าโปรเจ็กต์จะมีฐานข้อมูลได้สูงสุด 100 รายการ แต่ระบบจะกำหนดให้เฉพาะฐานข้อมูลแรกที่สร้างเป็นค่าเริ่มต้น
Cloud Firestore Security Rules จะใช้แยกกันสำหรับแต่ละฐานข้อมูลที่มีชื่อในโปรเจ็กต์ ซึ่งหมายความว่าหากคุณสร้างฐานข้อมูลหลายรายการ คุณจะต้องจัดการและใช้กฎ สำหรับแต่ละฐานข้อมูลแยกกัน ดูวิธีการโดยละเอียดเกี่ยวกับการใช้การอัปเดตได้ที่ใช้การอัปเดต
กฎการอ่าน/เขียนพื้นฐาน
กฎพื้นฐานประกอบด้วยคำสั่ง match ที่ระบุเส้นทางเอกสารและนิพจน์ allow ที่ให้รายละเอียดเมื่อได้รับอนุญาตให้อ่านข้อมูลที่ระบุ
service cloud.firestore { match /databases/{database}/documents { // Match any document in the 'cities' collection match /cities/{city} { allow read: if <condition>; allow write: if <condition>; } } }
คำสั่ง match ทั้งหมดควรชี้ไปยังเอกสาร ไม่ใช่คอลเล็กชัน คำสั่ง match
สามารถชี้ไปยังเอกสารที่เฉพาะเจาะจงได้ เช่น match /cities/SF หรือใช้ไวลด์การ์ด
เพื่อชี้ไปยังเอกสารใดก็ได้ในเส้นทางที่ระบุ เช่น match /cities/{city}
ในตัวอย่างด้านบน คำสั่ง match ใช้ไวยากรณ์ไวลด์การ์ด {city}
ซึ่งหมายความว่ากฎจะมีผลกับเอกสารใดก็ได้ในคอลเล็กชัน cities เช่น
/cities/SF หรือ /cities/NYC เมื่อมีการประเมินนิพจน์ allow ในคำสั่ง match
ตัวแปร city จะเปลี่ยนเป็นชื่อเอกสารเมือง เช่น
SF หรือ NYC
การดำเนินการแบบละเอียด
ในบางสถานการณ์ การแบ่งreadและwriteออกเป็นการดำเนินการที่ละเอียดยิ่งขึ้นอาจมีประโยชน์ ตัวอย่างเช่น แอปของคุณอาจต้องการบังคับใช้เงื่อนไขที่แตกต่างกันในการสร้างเอกสารมากกว่าการลบเอกสาร หรือคุณอาจต้องการอนุญาตการอ่านเอกสารเดียวแต่ปฏิเสธการค้นหาขนาดใหญ่
กฎ read สามารถแบ่งออกเป็น get และ list ในขณะที่กฎ write สามารถแบ่งออกเป็น create, update และ delete
service cloud.firestore { match /databases/{database}/documents { // A read rule can be divided into get and list rules match /cities/{city} { // Applies to single document read requests allow get: if <condition>; // Applies to queries and collection read requests allow list: if <condition>; } // A write rule can be divided into create, update, and delete rules match /cities/{city} { // Applies to writes to nonexistent documents allow create: if <condition>; // Applies to writes to existing documents allow update: if <condition>; // Applies to delete operations allow delete: if <condition>; } } }
ข้อมูลแบบลำดับชั้น
ข้อมูลใน Cloud Firestore จะจัดระเบียบเป็นคอลเล็กชันของเอกสาร และเอกสารแต่ละรายการอาจขยายลำดับชั้นผ่านคอลเล็กชันย่อย คุณควรทำความเข้าใจวิธีที่กฎการรักษาความปลอดภัยโต้ตอบกับข้อมูลแบบลำดับชั้น
พิจารณาสถานการณ์ที่เอกสารแต่ละฉบับในcitiesคอลเล็กชันมีlandmarksคอลเล็กชันย่อย กฎความปลอดภัยจะมีผลเฉพาะในเส้นทางที่ตรงกัน ดังนั้นการควบคุมการเข้าถึงที่กำหนดไว้ในคอลเล็กชัน cities จะไม่มีผลกับคอลเล็กชันย่อย landmarks แต่ให้เขียนกฎที่ชัดเจนเพื่อควบคุมการเข้าถึง
คอลเล็กชันย่อยแทน
service cloud.firestore { match /databases/{database}/documents { match /cities/{city} { allow read, write: if <condition>; // Explicitly define rules for the 'landmarks' subcollection match /landmarks/{landmark} { allow read, write: if <condition>; } } } }
เมื่อซ้อนคำสั่ง match เส้นทางของคำสั่ง match ด้านในจะสัมพันธ์กับเส้นทางของคำสั่ง match ด้านนอกเสมอ ดังนั้นชุดกฎต่อไปนี้
จึงมีความหมายเหมือนกัน
service cloud.firestore { match /databases/{database}/documents { match /cities/{city} { match /landmarks/{landmark} { allow read, write: if <condition>; } } } }
service cloud.firestore { match /databases/{database}/documents { match /cities/{city}/landmarks/{landmark} { allow read, write: if <condition>; } } }
ไวลด์การ์ดแบบเรียกซ้ำ
หากต้องการให้กฎมีผลกับลำดับชั้นที่ลึกเท่าใดก็ได้ ให้ใช้ไวยากรณ์สัญลักษณ์แทนแบบเรียกซ้ำ {name=**} เช่น
service cloud.firestore {
match /databases/{database}/documents {
// Matches any document in the cities collection as well as any document
// in a subcollection.
match /cities/{document=**} {
allow read, write: if <condition>;
}
}
}
เมื่อใช้ไวยากรณ์ไวลด์การ์ดแบบเรียกซ้ำ ตัวแปรไวลด์การ์ดจะมีส่วนเส้นทางที่ตรงกันทั้งหมด แม้ว่าเอกสารจะอยู่ในคอลเล็กชันย่อยที่ซ้อนกันลึกก็ตาม ตัวอย่างเช่น กฎที่แสดงด้านบนจะตรงกับ
เอกสารที่อยู่ใน /cities/SF/landmarks/coit_tower และค่าของ
ตัวแปร document จะเป็น SF/landmarks/coit_tower
อย่างไรก็ตาม โปรดทราบว่าลักษณะการทำงานของไวลด์การ์ดแบบเรียกซ้ำจะขึ้นอยู่กับเวอร์ชันของกฎ
เวอร์ชัน 1
กฎความปลอดภัยใช้เวอร์ชัน 1 โดยค่าเริ่มต้น ในเวอร์ชัน 1 ไวลด์การ์ดแบบเรียกซ้ำ
จะจับคู่รายการเส้นทางอย่างน้อย 1 รายการ แต่จะไม่จับคู่เส้นทางที่ว่างเปล่า ดังนั้น
match /cities/{city}/{document=**} จะจับคู่เอกสารในคอลเล็กชันย่อย แต่จะไม่จับคู่เอกสารในคอลเล็กชัน cities ในขณะที่ match /cities/{document=**} จะจับคู่
ทั้งเอกสารในคอลเล็กชัน cities และคอลเล็กชันย่อย
ไวลด์การ์ดแบบเรียกซ้ำต้องอยู่ท้ายคำสั่งที่ตรงกัน
เวอร์ชัน 2
ในกฎความปลอดภัยเวอร์ชัน 2 ไวลด์การ์ดแบบเรียกซ้ำจะจับคู่รายการเส้นทาง 0 รายการขึ้นไป
match/cities/{city}/{document=**} จะตรงกับเอกสารในคอลเล็กชันย่อย
รวมถึงเอกสารในคอลเล็กชัน cities
คุณต้องเลือกใช้เวอร์ชัน 2 โดยเพิ่ม rules_version = '2'; ที่ด้านบนของ
กฎความปลอดภัย
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // Matches any document in the cities collection as well as any document // in a subcollection. match /cities/{city}/{document=**} { allow read, write: if <condition>; } } }
คุณใช้ไวลด์การ์ดแบบเรียกซ้ำได้สูงสุด 1 รายการต่อคำสั่งที่ตรงกัน แต่ในเวอร์ชัน 2 คุณจะวางไวลด์การ์ดนี้ไว้ที่ใดก็ได้ในคำสั่งที่ตรงกัน เช่น
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // Matches any document in the songs collection group match /{path=**}/songs/{song} { allow read, write: if <condition>; } } }
หากใช้การค้นหากลุ่มคอลเล็กชัน คุณต้องใช้เวอร์ชัน 2 ดูการรักษาความปลอดภัยให้กับการค้นหากลุ่มคอลเล็กชัน
ใบแจ้งยอดที่ตรงกันซึ่งทับซ้อนกัน
เอกสารอาจตรงกับmatchคำสั่งมากกว่า 1 รายการ ในกรณีที่allowนิพจน์หลายรายการตรงกับคำขอ ระบบจะอนุญาตให้เข้าถึง
หากเงื่อนไขใดเป็นtrue
service cloud.firestore { match /databases/{database}/documents { // Matches any document in the 'cities' collection. match /cities/{city} { allow read, write: if false; } // Matches any document in the 'cities' collection or subcollections. match /cities/{document=**} { allow read, write: if true; } } }
ในตัวอย่างข้างต้น ระบบจะอนุญาตการอ่านและการเขียนทั้งหมดไปยังคอลเล็กชัน cities เนื่องจากกฎที่ 2 เป็น true เสมอ แม้ว่ากฎแรกจะเป็น false เสมอ
ขีดจำกัดของกฎความปลอดภัย
ขณะทำงานกับกฎความปลอดภัย โปรดทราบขีดจำกัดต่อไปนี้
| ขีดจำกัด | รายละเอียด |
|---|---|
จำนวนการเรียกใช้ exists(), get() และ getAfter() สูงสุดต่อคำขอ |
หากเกินขีดจำกัดใดขีดจำกัดหนึ่ง ระบบจะแสดงข้อผิดพลาด "ปฏิเสธสิทธิ์" ระบบอาจแคชการเรียกใช้การเข้าถึงเอกสารบางรายการ และการเรียกใช้ที่แคชจะไม่นับรวมในโควต้า |
ความลึกสูงสุดของคำสั่ง match ที่ซ้อนกัน |
10 |
ความยาวเส้นทางสูงสุดในส่วนเส้นทางที่อนุญาตภายในชุดคำสั่ง match ที่ซ้อนกัน |
100 |
จำนวนตัวแปรการจับเส้นทางสูงสุดที่อนุญาตภายในชุดคำสั่ง match ที่ซ้อนกัน
|
20 |
| ความลึกสูงสุดของการเรียกใช้ฟังก์ชัน | 20 |
| จำนวนอาร์กิวเมนต์ของฟังก์ชันสูงสุด | 7 |
จำนวนการเชื่อมโยงตัวแปร let สูงสุดต่อฟังก์ชัน |
10 |
| จำนวนการเรียกฟังก์ชันแบบเรียกซ้ำหรือแบบวนรอบสูงสุด | 0 (ไม่อนุญาต) |
| จำนวนสูงสุดของนิพจน์ที่ประเมินต่อคำขอ | 1,000 ราย |
| ขนาดสูงสุดของชุดกฎ | ชุดกฎต้องมีขนาดไม่เกิน 2 ขีดจำกัดต่อไปนี้
|