Cloud Firestore Security Rules ช่วยให้คุณควบคุมการเข้าถึงเอกสารและคอลเล็กชันในฐานข้อมูลได้ ไวยากรณ์กฎที่ยืดหยุ่นช่วยให้คุณสร้างกฎที่ตรงกับทุกสิ่งได้ ตั้งแต่การเขียนทั้งหมดไปยังทั้งฐานข้อมูลไปจนถึงการดำเนินการในเอกสารที่เฉพาะเจาะจง
คู่มือนี้จะอธิบายไวยากรณ์และโครงสร้างพื้นฐานของกฎความปลอดภัย รวมรูปแบบคำสั่งนี้เข้ากับเงื่อนไขของกฎความปลอดภัยเพื่อสร้างชุดกฎที่สมบูรณ์
การประกาศบริการและฐานข้อมูล
Cloud Firestore Security Rules ขึ้นต้นด้วยการประกาศต่อไปนี้เสมอ
service cloud.firestore {
match /databases/{database}/documents {
// ...
}
}
การประกาศ service cloud.firestore
จะกําหนดขอบเขตของกฎเป็น Cloud Firestore ซึ่งจะช่วยป้องกันไม่ให้ Cloud Firestore Security Rules ขัดแย้งกับกฎสําหรับผลิตภัณฑ์อื่นๆ เช่น Cloud Storage
การประกาศ match /databases/{database}/documents
จะระบุว่ากฎควรตรงกับฐานข้อมูล Cloud Firestore ในโปรเจ็กต์ ปัจจุบันแต่ละโปรเจ็กต์มีฐานข้อมูลเพียงฐานข้อมูลเดียวชื่อ (default)
กฎพื้นฐานของการอ่าน/เขียน
กฎพื้นฐานประกอบด้วยคำสั่ง 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 /cities/SF
หรือใช้ไวลด์การ์ดเพื่อชี้ไปยังเอกสารใดก็ได้ในเส้นทางที่ระบุ เช่น match /cities/{city}
ในตัวอย่างข้างต้น คำสั่งการทํางานแบบตรงทั้งหมดใช้ไวยากรณ์ไวลด์การ์ด {city}
ซึ่งหมายความว่ากฎจะมีผลกับเอกสารทุกรายการในคอลเล็กชัน cities
เช่น /cities/SF
หรือ /cities/NYC
เมื่อประเมินนิพจน์ allow
ในคำสั่งการจับคู่แล้ว ตัวแปร 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
เสมอ แม้ว่ากฎที่ 1 จะเป็น false
เสมอก็ตาม
ขีดจํากัดของกฎความปลอดภัย
โปรดคำนึงถึงขีดจำกัดต่อไปนี้เมื่อใช้กฎความปลอดภัย
ขีดจำกัด | รายละเอียด |
---|---|
จำนวนการเรียกใช้ exists() , get() และ getAfter() สูงสุดต่อคำขอ |
หากเกินขีดจำกัดดังกล่าว ระบบจะแสดงข้อผิดพลาด "ถูกปฏิเสธสิทธิ์" การเรียกใช้การเข้าถึงเอกสารบางรายการอาจมีการแคชไว้ และการเรียกใช้ที่แคชไว้จะไม่นับรวมในขีดจำกัด |
ความลึกสูงสุดของคำสั่ง match ที่ฝังอยู่ |
10 |
ความยาวเส้นทางสูงสุดในส่วนเส้นทางที่อนุญาตภายในชุดคำสั่ง match ที่ฝังอยู่ |
100 |
จํานวนตัวแปรการบันทึกเส้นทางสูงสุดที่อนุญาตภายในชุดคำสั่ง match ที่ฝังอยู่ |
20 |
ความลึกสูงสุดของการเรียกใช้ฟังก์ชัน | 20 |
จํานวนอาร์กิวเมนต์ของฟังก์ชันสูงสุด | 7 |
จำนวนการเชื่อมโยงตัวแปร let สูงสุดต่อฟังก์ชัน |
10 |
จํานวนการเรียกฟังก์ชันแบบวนซ้ำหรือแบบวนสูงสุด | 0 (not permitted) |
จำนวนนิพจน์สูงสุดที่ประเมินต่อคำขอ | 1,000 ราย |
ขนาดสูงสุดของชุดกฎ | ชุดกฎต้องเป็นไปตามขีดจํากัดขนาด 2 ข้อต่อไปนี้
|