คู่มือนี้สร้างขึ้นจากคำแนะนำ กฎความปลอดภัยการจัดโครงสร้าง เพื่อแสดงวิธีเพิ่มเงื่อนไขในกฎความปลอดภัยของ Cloud Firestore หากคุณไม่คุ้นเคยกับพื้นฐานของกฎความปลอดภัยของ Cloud Firestore โปรดดูคู่มือ การเริ่มต้น ใช้งาน
โครงสร้างหลักของกฎความปลอดภัยของ Cloud Firestore คือเงื่อนไข เงื่อนไขคือนิพจน์บูลีนที่กำหนดว่าการดำเนินการเฉพาะควรได้รับอนุญาตหรือปฏิเสธ ใช้กฎความปลอดภัยเพื่อเขียนเงื่อนไขที่ตรวจสอบการรับรองความถูกต้องของผู้ใช้ ตรวจสอบข้อมูลขาเข้า หรือแม้แต่เข้าถึงส่วนอื่นๆ ของฐานข้อมูลของคุณ
การตรวจสอบสิทธิ์
รูปแบบกฎความปลอดภัยที่พบบ่อยที่สุดรูปแบบหนึ่งคือการควบคุมการเข้าถึงตามสถานะการตรวจสอบสิทธิ์ของผู้ใช้ ตัวอย่างเช่น แอปของคุณอาจต้องการให้ผู้ใช้ที่ลงชื่อเข้าใช้เท่านั้นเขียนข้อมูลได้:
service cloud.firestore {
match /databases/{database}/documents {
// Allow the user to access documents in the "cities" collection
// only if they are authenticated.
match /cities/{city} {
allow read, write: if request.auth != null;
}
}
}
รูปแบบทั่วไปอีกรูปแบบหนึ่งคือการทำให้แน่ใจว่าผู้ใช้สามารถอ่านและเขียนข้อมูลของตนเองได้เท่านั้น:
service cloud.firestore {
match /databases/{database}/documents {
// Make sure the uid of the requesting user matches name of the user
// document. The wildcard expression {userId} makes the userId variable
// available in rules.
match /users/{userId} {
allow read, update, delete: if request.auth != null && request.auth.uid == userId;
allow create: if request.auth != null;
}
}
}
หากแอปของคุณใช้การตรวจสอบสิทธิ์ Firebase หรือ Google Cloud Identity Platform ตัวแปร request.auth
จะมีข้อมูลการตรวจสอบสิทธิ์สำหรับไคลเอ็นต์ที่ขอข้อมูล สำหรับข้อมูลเพิ่มเติมเกี่ยวกับ request.auth
โปรดดู เอกสารอ้างอิง
การตรวจสอบข้อมูล
แอพจำนวนมากเก็บข้อมูลการควบคุมการเข้าถึงเป็นฟิลด์บนเอกสารในฐานข้อมูล กฎความปลอดภัยของ Cloud Firestore สามารถอนุญาตหรือปฏิเสธการเข้าถึงแบบไดนามิกตามข้อมูลเอกสาร:
service cloud.firestore {
match /databases/{database}/documents {
// Allow the user to read data if the document has the 'visibility'
// field set to 'public'
match /cities/{city} {
allow read: if resource.data.visibility == 'public';
}
}
}
ตัวแปร resource
อ้างอิงถึงเอกสารที่ร้องขอ และ resource.data
เป็นแผนที่ของฟิลด์และค่าทั้งหมดที่จัดเก็บไว้ในเอกสาร สำหรับข้อมูลเพิ่มเติมเกี่ยวกับตัวแปร resource
โปรดดู เอกสารอ้างอิง
เมื่อเขียนข้อมูล คุณอาจต้องการเปรียบเทียบข้อมูลขาเข้ากับข้อมูลที่มีอยู่ ในกรณีนี้ หากชุดกฎของคุณอนุญาตให้มีการเขียนที่รอดำเนินการ ตัวแปร request.resource
จะมีสถานะในอนาคตของเอกสาร สำหรับการดำเนินการ update
ที่แก้ไขเฉพาะชุดย่อยของฟิลด์เอกสาร ตัวแปร request.resource
จะมีสถานะเอกสารที่รอดำเนินการหลังการดำเนินการ คุณสามารถตรวจสอบค่าของฟิลด์ใน request.resource
เพื่อป้องกันการอัปเดตข้อมูลที่ไม่ต้องการหรือไม่สอดคล้องกัน:
service cloud.firestore {
match /databases/{database}/documents {
// Make sure all cities have a positive population and
// the name is not changed
match /cities/{city} {
allow update: if request.resource.data.population > 0
&& request.resource.data.name == resource.data.name;
}
}
}
เข้าถึงเอกสารอื่นๆ
การใช้ฟังก์ชัน get()
และ exists()
กฎความปลอดภัยของคุณสามารถประเมินคำขอที่เข้ามาเทียบกับเอกสารอื่นๆ ในฐานข้อมูลได้ ฟังก์ชัน get()
และ exists()
ต่างก็คาดหวังเส้นทางเอกสารที่ระบุโดยสมบูรณ์ เมื่อใช้ตัวแปรเพื่อสร้างเส้นทางสำหรับ get()
และ exists()
คุณต้องหลีกเลี่ยงตัวแปรอย่างชัดเจนโดยใช้ไวยากรณ์ $(variable)
ในตัวอย่างด้านล่าง ตัวแปร database
ถูกจับโดยคำสั่งการจับคู่ที่ match /databases/{database}/documents
และใช้เพื่อสร้างเส้นทาง:
service cloud.firestore {
match /databases/{database}/documents {
match /cities/{city} {
// Make sure a 'users' document exists for the requesting user before
// allowing any writes to the 'cities' collection
allow create: if request.auth != null && exists(/databases/$(database)/documents/users/$(request.auth.uid))
// Allow the user to delete cities if their user document has the
// 'admin' field set to 'true'
allow delete: if request.auth != null && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true
}
}
}
สำหรับการเขียน คุณสามารถใช้ getAfter()
เพื่อเข้าถึงสถานะของเอกสารหลังจากที่ธุรกรรมหรือชุดของการเขียนเสร็จสิ้น แต่ก่อนที่ธุรกรรมหรือชุดจะคอมมิต เช่นเดียวกับ get()
getAfter()
ใช้เส้นทางเอกสารที่ระบุโดยสมบูรณ์ คุณสามารถใช้ getAfter()
เพื่อกำหนดชุดของการเขียนที่ต้องทำร่วมกันเป็นธุรกรรมหรือแบทช์
เข้าถึงขีดจำกัดการโทร
มีการจำกัดการเรียกการเข้าถึงเอกสารต่อการประเมินชุดกฎ:
- 10 สำหรับคำขอเอกสารเดียวและคำขอค้นหา
20 สำหรับการอ่านเอกสารหลายรายการ ธุรกรรม และการเขียนแบบแบตช์ ขีดจำกัดก่อนหน้าที่ 10 ยังใช้กับการดำเนินการแต่ละครั้ง
ตัวอย่างเช่น สมมติว่าคุณสร้างคำขอเขียนเป็นชุดโดยมีการดำเนินการเขียน 3 รายการ และกฎความปลอดภัยใช้การเรียกการเข้าถึงเอกสาร 2 รายการเพื่อตรวจสอบความถูกต้องของการเขียนแต่ละครั้ง ในกรณีนี้ การเขียนแต่ละครั้งจะใช้การเรียกการเข้าถึง 2 ใน 10 รายการ และคำขอเขียนแบบแบตช์ใช้ 6 รายการจาก 20 การเรียกการเข้าถึง
เกินขีดจำกัดอย่างใดอย่างหนึ่งส่งผลให้เกิดข้อผิดพลาดในการปฏิเสธการอนุญาต การโทรเข้าถึงเอกสารบางรายการอาจถูกแคชไว้ และการเรียกใช้ที่แคชจะไม่นับรวมในขีดจำกัด
สำหรับคำอธิบายโดยละเอียดว่าขีดจำกัดเหล่านี้ส่งผลต่อธุรกรรมและการเขียนแบบแบตช์อย่างไร โปรดดูคำแนะนำสำหรับ การรักษาความปลอดภัยการดำเนินการปรมาณู
เข้าถึงการโทรและราคา
การใช้ฟังก์ชันเหล่านี้จะดำเนินการอ่านในฐานข้อมูลของคุณ ซึ่งหมายความว่าคุณจะถูกเรียกเก็บเงินสำหรับการอ่านเอกสารแม้ว่ากฎของคุณจะปฏิเสธคำขอก็ตาม ดู ราคา Cloud Firestore สำหรับข้อมูลการเรียกเก็บเงินที่เฉพาะเจาะจงมากขึ้น
ฟังก์ชั่นที่กำหนดเอง
เนื่องจากกฎความปลอดภัยของคุณมีความซับซ้อนมากขึ้น คุณอาจต้องการรวมชุดเงื่อนไขในฟังก์ชันที่คุณสามารถนำมาใช้ซ้ำได้ในชุดกฎของคุณ กฎความปลอดภัยรองรับฟังก์ชันที่กำหนดเอง ไวยากรณ์สำหรับฟังก์ชันที่กำหนดเองนั้นคล้ายกับ JavaScript แต่ฟังก์ชันกฎความปลอดภัยเขียนด้วยภาษาเฉพาะโดเมนซึ่งมีข้อจำกัดที่สำคัญบางประการ:
- ฟังก์ชันสามารถมีคำสั่ง
return
ได้เพียงคำสั่งเดียว พวกเขาไม่สามารถมีตรรกะเพิ่มเติมใด ๆ ตัวอย่างเช่น ไม่สามารถรันลูปหรือเรียกใช้บริการภายนอกได้ - ฟังก์ชันสามารถเข้าถึงฟังก์ชันและตัวแปรได้โดยอัตโนมัติจากขอบเขตที่กำหนดไว้ ตัวอย่างเช่น ฟังก์ชั่นที่กำหนดไว้ภายในขอบเขต
service cloud.firestore
สามารถเข้าถึงตัวแปรresource
และฟังก์ชันในตัว เช่นget()
และexists()
- ฟังก์ชันอาจเรียกใช้ฟังก์ชันอื่นๆ แต่ไม่สามารถเรียกซ้ำได้ ความลึกของสแต็กการโทรทั้งหมดถูกจำกัดที่ 10
- ในกฎเวอร์ชัน
v2
ฟังก์ชันสามารถกำหนดตัวแปรได้โดยใช้คีย์เวิร์ดlet
ฟังก์ชั่นสามารถมีได้มากถึง 10 การเชื่อมโยง แต่จะต้องลงท้ายด้วยคำสั่ง return
ฟังก์ชั่นถูกกำหนดด้วยคีย์เวิร์ดของ function
และรับอาร์กิวเมนต์เป็นศูนย์หรือมากกว่า ตัวอย่างเช่น คุณอาจต้องการรวมเงื่อนไขสองประเภทที่ใช้ในตัวอย่างด้านบนเป็นฟังก์ชันเดียว:
service cloud.firestore {
match /databases/{database}/documents {
// True if the user is signed in or the requested data is 'public'
function signedInOrPublic() {
return request.auth.uid != null || resource.data.visibility == 'public';
}
match /cities/{city} {
allow read, write: if signedInOrPublic();
}
match /users/{user} {
allow read, write: if signedInOrPublic();
}
}
}
การใช้ฟังก์ชันในกฎความปลอดภัยทำให้สามารถบำรุงรักษาได้มากขึ้นเมื่อกฎของคุณมีความซับซ้อนมากขึ้น
กฎไม่ใช่ตัวกรอง
เมื่อคุณรักษาความปลอดภัยข้อมูลของคุณและเริ่มเขียนคำค้นหาแล้ว โปรดทราบว่ากฎความปลอดภัยไม่ใช่ตัวกรอง คุณไม่สามารถเขียนแบบสอบถามสำหรับเอกสารทั้งหมดในคอลเล็กชันและคาดหวังให้ Cloud Firestore ส่งคืนเฉพาะเอกสารที่ไคลเอนต์ปัจจุบันมีสิทธิ์เข้าถึง
ตัวอย่างเช่น ใช้กฎความปลอดภัยต่อไปนี้:
service cloud.firestore {
match /databases/{database}/documents {
// Allow the user to read data if the document has the 'visibility'
// field set to 'public'
match /cities/{city} {
allow read: if resource.data.visibility == 'public';
}
}
}
ถูกปฏิเสธ : กฎนี้ปฏิเสธการสืบค้นต่อไปนี้ เนื่องจากชุดผลลัพธ์สามารถรวมเอกสารที่ไม่ visibility
public
:
เว็บ
db.collection("cities").get() .then(function(querySnapshot) { querySnapshot.forEach(function(doc) { console.log(doc.id, " => ", doc.data()); }); });
อนุญาต : กฎนี้อนุญาตการสืบค้นข้อมูลต่อไปนี้เนื่องจากส่วนคำสั่ง where("visibility", "==", "public")
รับประกันว่าชุดผลลัพธ์เป็นไปตามเงื่อนไขของกฎ:
เว็บ
db.collection("cities").where("visibility", "==", "public").get() .then(function(querySnapshot) { querySnapshot.forEach(function(doc) { console.log(doc.id, " => ", doc.data()); }); });
กฎความปลอดภัยของ Cloud Firestore จะประเมินการสืบค้นแต่ละรายการโดยพิจารณาจากผลลัพธ์ที่เป็นไปได้ และทำตามคำขอไม่สำเร็จหากส่งคืนเอกสารที่ไคลเอ็นต์ไม่มีสิทธิ์อ่าน แบบสอบถามต้องเป็นไปตามข้อจำกัดที่กำหนดโดยกฎความปลอดภัยของคุณ สำหรับข้อมูลเพิ่มเติมเกี่ยวกับกฎความปลอดภัยและการสืบค้น โปรดดู ที่การสืบค้นข้อมูลอย่างปลอดภัย
ขั้นตอนถัดไป
- เรียนรู้ว่า กฎความปลอดภัยส่งผลต่อการสืบค้นของคุณ อย่างไร
- เรียนรู้วิธี จัดโครงสร้างกฎความปลอดภัย
- อ่านการ อ้างอิงกฎความปลอดภัย