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