กฎความปลอดภัยของ Firebase ใช้ประโยชน์จากภาษาแบบกำหนดเองที่ยืดหยุ่น ทรงพลัง ซึ่งรองรับความซับซ้อนและความละเอียดที่หลากหลาย คุณสามารถกำหนดให้กฎเป็นแบบเฉพาะเจาะจงหรือทั่วไปตามที่เหมาะสมสำหรับแอปของคุณ กฎฐานข้อมูลเรียลไทม์ใช้ไวยากรณ์ที่ดูเหมือน JavaScript ในโครงสร้าง JSON กฎของ Cloud Firestore และ Cloud Storage ใช้ภาษาตาม Common Expression Language (CEL) ซึ่งสร้างขึ้นบน CEL พร้อมคำสั่งจับ match
และ allow
ที่รองรับการเข้าถึงแบบมีเงื่อนไข
เนื่องจากภาษาเหล่านี้เป็นภาษาที่กำหนดเอง จึงมีช่วงการเรียนรู้ ใช้คู่มือนี้เพื่อทำความเข้าใจภาษาของกฎให้ดียิ่งขึ้นเมื่อคุณเจาะลึกลงไปในกฎที่ซับซ้อนมากขึ้น
เลือกผลิตภัณฑ์เพื่อเรียนรู้เพิ่มเติมเกี่ยวกับกฎของผลิตภัณฑ์
โครงสร้างพื้นฐาน
Cloud Firestore
กฎความปลอดภัยของ Firebase ใน Cloud Firestore และ Cloud Storage ใช้โครงสร้างและไวยากรณ์ต่อไปนี้:
service <<name>> {
// Match the resource path.
match <<path>> {
// Allow the request if the following conditions are true.
allow <<methods>> : if <<condition>>
}
}
แนวคิดหลักต่อไปนี้มีความสำคัญต่อการทำความเข้าใจเมื่อคุณสร้างกฎ:
- คำขอ: เมธอดหรือเมธอดที่เรียกใช้ในคำสั่ง
allow
นี่เป็นวิธีที่คุณอนุญาตให้เรียกใช้ วิธีการมาตรฐานคือ:get
,list
,create
,update
และdelete
วิธีการอำนวยความสะดวกread
และwrite
ทำให้สามารถเข้าถึงการอ่านและเขียนแบบกว้างบนฐานข้อมูลหรือพาธหน่วยเก็บข้อมูลที่ระบุ - เส้นทาง: ฐานข้อมูลหรือตำแหน่งที่เก็บข้อมูล ซึ่งแสดงเป็นเส้นทาง URI
- กฎ: คำสั่ง
allow
ซึ่งรวมถึงเงื่อนไขที่อนุญาตคำขอหากประเมินเป็นจริง
แต่ละแนวคิดเหล่านี้มีรายละเอียดเพิ่มเติมด้านล่าง
การจัดเก็บเมฆ
กฎความปลอดภัยของ Firebase ใน Cloud Firestore และ Cloud Storage ใช้โครงสร้างและไวยากรณ์ต่อไปนี้:
service <<name>> {
// Match the resource path.
match <<path>> {
// Allow the request if the following conditions are true.
allow <<methods>> : if <<condition>>
}
}
แนวคิดหลักต่อไปนี้มีความสำคัญต่อการทำความเข้าใจเมื่อคุณสร้างกฎ:
- คำขอ: เมธอดหรือเมธอดที่เรียกใช้ในคำสั่ง
allow
นี่เป็นวิธีที่คุณอนุญาตให้เรียกใช้ วิธีการมาตรฐานคือ:get
,list
,create
,update
และdelete
วิธีการอำนวยความสะดวกread
และwrite
ทำให้สามารถเข้าถึงการอ่านและเขียนแบบกว้างบนฐานข้อมูลหรือพาธหน่วยเก็บข้อมูลที่ระบุ - เส้นทาง: ฐานข้อมูลหรือตำแหน่งที่เก็บข้อมูล ซึ่งแสดงเป็นเส้นทาง URI
- กฎ: คำสั่ง
allow
ซึ่งรวมถึงเงื่อนไขที่อนุญาตคำขอหากประเมินเป็นจริง
แต่ละแนวคิดเหล่านี้มีรายละเอียดเพิ่มเติมด้านล่าง
ฐานข้อมูลเรียลไทม์
ในฐานข้อมูลเรียลไทม์ กฎความปลอดภัยของ Firebase ประกอบด้วยนิพจน์คล้าย JavaScript ที่มีอยู่ในเอกสาร JSON
พวกเขาใช้ไวยากรณ์ต่อไปนี้:
{
"rules": {
"<<path>>": {
// Allow the request if the condition for each method is true.
".read": <<condition>>,
".write": <<condition>>,
".validate": <<condition>>
}
}
}
มีสามองค์ประกอบพื้นฐานในกฎ:
- เส้นทาง: ตำแหน่งฐานข้อมูล สิ่งนี้สะท้อนโครงสร้าง JSON ของฐานข้อมูลของคุณ
- คำขอ: นี่คือวิธีการที่กฎใช้ในการให้สิทธิ์การเข้าถึง กฎ
read
และwrite
ให้สิทธิ์การเข้าถึงแบบอ่านและเขียนแบบกว้าง ในขณะที่กฎvalidate
ความถูกต้องทำหน้าที่เป็นการตรวจสอบสำรองเพื่อให้สิทธิ์การเข้าถึงตามข้อมูลขาเข้าหรือที่มีอยู่ - เงื่อนไข: เงื่อนไขที่อนุญาตคำขอหากประเมินเป็นจริง
การสร้างกฎ
Cloud Firestore
องค์ประกอบพื้นฐานของกฎใน Cloud Firestore และ Cloud Storage มีดังนี้:
- การประกาศ
service
: ประกาศผลิตภัณฑ์ Firebase ที่กฎมีผล - บล็อก
match
: กำหนดเส้นทางในฐานข้อมูลหรือที่เก็บข้อมูลที่กฎใช้ - คำสั่ง
allow
: ให้เงื่อนไขสำหรับการให้สิทธิ์การเข้าถึงโดยแยกตามวิธีการ วิธีการที่รองรับ ได้แก่get
list
create
update
delete
และวิธีการอำนวยความสะดวกในread
และwrite
- การประกาศ
function
เพิ่มเติม: ให้ความสามารถในการรวมและรวมเงื่อนไขเพื่อใช้ในหลายๆ กฎ
service
ประกอบด้วยหนึ่งบล็อกหรือมากกว่า match
คำสั่ง allow
ที่ให้เงื่อนไขการเข้าถึงคำขอ ตัวแปร request
และ resource
พร้อมใช้งานในเงื่อนไขของกฎ ภาษากฎความปลอดภัยของ Firebase ยังรองรับการประกาศ function
อีกด้วย
เวอร์ชันไวยากรณ์
คำสั่ง syntax
ระบุเวอร์ชันของภาษากฎ Firebase ที่ใช้ในการเขียนต้นฉบับ เวอร์ชันล่าสุดของภาษาคือ v2
rules_version = '2';
service cloud.firestore {
...
}
ถ้าไม่ได้ระบุคำสั่ง rules_version
กฎของคุณจะได้รับการประเมินโดยใช้เครื่องมือ v1
บริการ
การประกาศ service
จะกำหนดผลิตภัณฑ์หรือบริการของ Firebase ที่กฎของคุณมีผล คุณสามารถรวมการประกาศ service
ได้เพียงรายการเดียวต่อไฟล์ต้นทาง
Cloud Firestore
service cloud.firestore {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
การจัดเก็บเมฆ
service firebase.storage {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
หากคุณกำหนดกฎสำหรับทั้ง Cloud Firestore และ Cloud Storage โดยใช้ Firebase CLI คุณจะต้องรักษากฎเหล่านั้นในไฟล์แยกกัน
จับคู่
บล็อก match
จะประกาศรูปแบบ path
ที่จับคู่กับเส้นทางสำหรับการดำเนินการที่ร้องขอ ( request.path
ที่เข้ามา) เนื้อความของ match
ต้องมีอย่างน้อยหนึ่งบล็อกการ match
ที่ซ้อน allow
หรือการประกาศ function
เส้นทางในบล็อก match
ที่ซ้อนกันจะสัมพันธ์กับเส้นทางในบล็อก match
หลัก
รูปแบบ path
เป็นชื่อที่เหมือนไดเร็กทอรีซึ่งอาจมีตัวแปรหรือสัญลักษณ์แทน รูปแบบ path
ช่วยให้สามารถจับคู่เส้นทางเดียวและหลายเส้นทางได้ ตัวแปรใดๆ ที่เชื่อมโยงใน path
จะมองเห็นได้ภายในขอบเขต match
หรือขอบเขตที่ซ้อนกันใดๆ ที่ path
ถูกประกาศ
การจับคู่กับรูปแบบ path
อาจเป็นบางส่วนหรือทั้งหมดก็ได้:
- ตรงกันบางส่วน: รูปแบบ
path
เป็นคำนำหน้าตรงกับrequest.path
- การจับคู่ที่สมบูรณ์: รูปแบบ
path
ตรงกับทั้งrequest.path
เมื่อจับคู่ สมบูรณ์ แล้ว กฎภายในบล็อกจะได้รับการประเมิน เมื่อทำการจับคู่ บางส่วน กฎ match
แบบซ้อนจะได้รับการทดสอบเพื่อดูว่า path
แบบซ้อนใดๆ จะทำการจับคู่ ให้สมบูรณ์ หรือไม่
กฎใน match
ที่สมบูรณ์ แต่ละรายการจะได้รับการประเมินเพื่อพิจารณาว่าจะอนุญาตคำขอหรือไม่ หากกฎการจับคู่ใดๆ ให้สิทธิ์เข้าถึง คำขอนั้นจะได้รับอนุญาต หากไม่มีกฎที่ตรงกันให้สิทธิ์การเข้าถึง คำขอจะถูกปฏิเสธ
// Given request.path == /example/hello/nested/path the following
// declarations indicate whether they are a partial or complete match and
// the value of any variables visible within the scope.
service firebase.storage {
// Partial match.
match /example/{singleSegment} { // `singleSegment` == 'hello'
allow write; // Write rule not evaluated.
// Complete match.
match /nested/path { // `singleSegment` visible in scope.
allow read; // Read rule is evaluated.
}
}
// Complete match.
match /example/{multiSegment=**} { // `multiSegment` == /hello/nested/path
allow read; // Read rule is evaluated.
}
}
ตามตัวอย่างด้านบน การประกาศ path
สนับสนุนตัวแปรต่อไปนี้:
- ไวด์การ์ดกลุ่มเดียว: ตัวแปรไวด์การ์ดถูกประกาศในเส้นทางโดยล้อมตัวแปรไว้ในวงเล็บปีกกา:
{variable}
ตัวแปรนี้สามารถเข้าถึงได้ภายในคำสั่งการmatch
เป็นstring
- ไวด์การ์ดแบบเรียกซ้ำ: ไวลด์การ์ดแบบเรียกซ้ำหรือหลายเซกเมนต์จะจับคู่พาธหลายเซกเมนต์ที่หรือต่ำกว่าพาธ ไวด์การ์ดนี้ตรงกับเส้นทางทั้งหมดด้านล่างตำแหน่งที่ตั้งที่คุณตั้งไว้ คุณสามารถประกาศได้โดยเพิ่มสตริง
=**
ที่ส่วนท้ายของตัวแปรกลุ่มของคุณ:{variable=**}
ตัวแปรนี้สามารถเข้าถึงได้ภายในคำสั่งmatch
เป็นวัตถุpath
อนุญาต
บล็อก match
ประกอบด้วยคำสั่ง allow
ตั้งแต่หนึ่งคำสั่งขึ้นไป นี่คือกฎที่แท้จริงของคุณ คุณสามารถใช้กฎ allow
กับเมธอดอย่างน้อยหนึ่งเมธอด เงื่อนไขในคำสั่ง allow
ต้องประเมินเป็นจริงสำหรับ Cloud Firestore หรือ Cloud Storage เพื่อให้อนุญาตคำขอที่เข้ามา คุณยังสามารถเขียนคำสั่ง allow
โดยไม่มีเงื่อนไข เช่น allow read
ถ้าคำสั่ง allow
ไม่มีเงื่อนไข อย่างไรก็ตาม จะอนุญาตคำขอสำหรับวิธีการนั้นเสมอ
หากเป็นไปตามกฎ allow
ใดๆ สำหรับเมธอด คำขอจะได้รับอนุญาต นอกจากนี้ หากกฎที่กว้างกว่านี้ให้สิทธิ์การเข้าถึง กฎจะอนุญาตการเข้าถึงและไม่สนใจกฎที่ละเอียดกว่านี้ซึ่งอาจจำกัดการเข้าถึง
พิจารณาตัวอย่างต่อไปนี้ ซึ่งผู้ใช้สามารถอ่านหรือลบไฟล์ของตนเองได้ กฎที่ละเอียดยิ่งขึ้นจะอนุญาตให้เขียนได้ก็ต่อเมื่อผู้ใช้ที่ขอให้เขียนเป็นเจ้าของไฟล์และไฟล์นั้นเป็น PNG ผู้ใช้สามารถลบไฟล์ใดๆ ที่พาธย่อย — แม้ว่าจะไม่ใช่ PNG — เนื่องจากกฎก่อนหน้านี้อนุญาต
service firebase.storage {
// Allow the requestor to read or delete any resource on a path under the
// user directory.
match /users/{userId}/{anyUserFile=**} {
allow read, delete: if request.auth != null && request.auth.uid == userId;
}
// Allow the requestor to create or update their own images.
// When 'request.method' == 'delete' this rule and the one matching
// any path under the user directory would both match and the `delete`
// would be permitted.
match /users/{userId}/images/{imageId} {
// Whether to permit the request depends on the logical OR of all
// matched rules. This means that even if this rule did not explicitly
// allow the 'delete' the earlier rule would have.
allow write: if request.auth != null && request.auth.uid == userId && imageId.matches('*.png');
}
}
วิธี
คำสั่ง allow
แต่ละรายการมีวิธีการที่ให้สิทธิ์การเข้าถึงสำหรับคำขอขาเข้าของวิธีการเดียวกัน
วิธี | ประเภทของคำขอ |
---|---|
วิธีอำนวยความสะดวก | |
read | คำขออ่านประเภทใดก็ได้ |
write | คำขอเขียนประเภทใดก็ได้ |
วิธีการมาตรฐาน | |
get | อ่านคำขอสำหรับเอกสารหรือไฟล์เดียว |
list | อ่านคำขอสำหรับแบบสอบถามและคอลเลกชัน |
create | เขียนเอกสารหรือไฟล์ใหม่ |
update | เขียนไปยังเอกสารฐานข้อมูลที่มีอยู่หรืออัปเดตข้อมูลเมตาของไฟล์ |
delete | ลบข้อมูล |
คุณไม่สามารถซ้อนทับวิธีการอ่านในบล็อก match
เดียวกันหรือวิธีการเขียนที่ขัดแย้งกันในการประกาศ path
เดียวกัน
ตัวอย่างเช่น กฎต่อไปนี้จะล้มเหลว:
service bad.example {
match /rules/with/overlapping/methods {
// This rule allows reads to all authenticated users
allow read: if request.auth != null;
match another/subpath {
// This secondary, more specific read rule causes an error
allow get: if request.auth != null && request.auth.uid == "me";
// Overlapping write methods in the same path cause an error as well
allow write: if request.auth != null;
allow create: if request.auth != null && request.auth.uid == "me";
}
}
}
การทำงาน
เมื่อกฎความปลอดภัยของคุณซับซ้อนมากขึ้น คุณอาจต้องการรวมชุดเงื่อนไขในฟังก์ชันที่คุณใช้ซ้ำได้ในชุดกฎของคุณ กฎความปลอดภัยรองรับฟังก์ชันแบบกำหนดเอง ไวยากรณ์สำหรับฟังก์ชันแบบกำหนดเองจะคล้ายกับ JavaScript แต่ฟังก์ชันกฎความปลอดภัยเขียนด้วยภาษาเฉพาะโดเมนซึ่งมีข้อจำกัดที่สำคัญบางประการ:
- ฟังก์ชันสามารถมีคำสั่ง
return
เดียวเท่านั้น ไม่สามารถมีตรรกะเพิ่มเติมใดๆ ตัวอย่างเช่น พวกเขาไม่สามารถดำเนินการวนซ้ำหรือเรียกใช้บริการภายนอกได้ - ฟังก์ชันสามารถเข้าถึงฟังก์ชันและตัวแปรโดยอัตโนมัติจากขอบเขตที่กำหนดไว้ ตัวอย่างเช่น ฟังก์ชันที่กำหนดภายในขอบเขต
service cloud.firestore
มีสิทธิ์เข้าถึงตัวแปรresource
และฟังก์ชันในตัว เช่นget()
และexists()
- ฟังก์ชันอาจเรียกใช้ฟังก์ชันอื่นแต่ไม่สามารถเรียกซ้ำได้ ความลึกของ call stack ทั้งหมดจำกัดอยู่ที่ 20
- ในกฎเวอร์ชัน
v2
ฟังก์ชันสามารถกำหนดตัวแปรโดยใช้คำหลักlet
ฟังก์ชันสามารถมีได้มากถึง 10 การรวม let แต่ต้องลงท้ายด้วยคำสั่ง 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();
}
}
}
นี่คือตัวอย่างที่แสดงอาร์กิวเมนต์ของฟังก์ชันและการมอบหมายงาน คำสั่งการมอบหมายงานให้ต้องคั่นด้วยเครื่องหมายอัฒภาค
function isAuthorOrAdmin(userId, article) {
let isAuthor = article.author == userId;
let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
return isAuthor || isAdmin;
}
โปรดทราบว่าการกำหนด isAdmin
บังคับใช้การค้นหาคอลเลกชันของผู้ดูแลระบบอย่างไร สำหรับการประเมินแบบขี้เกียจโดยไม่ต้องมีการค้นหาที่ไม่จำเป็น ให้ใช้ประโยชน์จากลักษณะการลัดวงจรของ &&
(AND) และ ||
(หรือ) การเปรียบเทียบเพื่อเรียกฟังก์ชันที่สองเฉพาะในกรณีที่ isAuthor
ถูกแสดงว่าเป็นจริง (สำหรับ &&
การเปรียบเทียบ) หรือเท็จ (สำหรับ ||
การเปรียบเทียบ)
function isAdmin(userId) {
return exists(/databases/$(database)/documents/admins/$(userId));
}
function isAuthorOrAdmin(userId, article) {
let isAuthor = article.author == userId;
// `||` is short-circuiting; isAdmin called only if isAuthor == false.
return isAuthor || isAdmin(userId);
}
การใช้ฟังก์ชันในกฎความปลอดภัยทำให้รักษาได้มากขึ้นตามความซับซ้อนของกฎที่เพิ่มขึ้น
การจัดเก็บเมฆ
องค์ประกอบพื้นฐานของกฎใน Cloud Firestore และ Cloud Storage มีดังนี้:
- การประกาศ
service
: ประกาศผลิตภัณฑ์ Firebase ที่กฎมีผล - บล็อก
match
: กำหนดเส้นทางในฐานข้อมูลหรือที่เก็บข้อมูลที่กฎใช้ - คำสั่ง
allow
: ให้เงื่อนไขสำหรับการให้สิทธิ์การเข้าถึงโดยแยกตามวิธีการ วิธีการที่รองรับ ได้แก่get
list
create
update
delete
และวิธีการอำนวยความสะดวกในread
และwrite
- การประกาศ
function
เพิ่มเติม: ให้ความสามารถในการรวมและรวมเงื่อนไขเพื่อใช้ในหลายๆ กฎ
service
ประกอบด้วยหนึ่งบล็อกหรือมากกว่า match
คำสั่ง allow
ที่ให้เงื่อนไขการเข้าถึงคำขอ ตัวแปร request
และ resource
พร้อมใช้งานในเงื่อนไขของกฎ ภาษากฎความปลอดภัยของ Firebase ยังรองรับการประกาศ function
อีกด้วย
เวอร์ชันไวยากรณ์
คำสั่ง syntax
ระบุเวอร์ชันของภาษากฎ Firebase ที่ใช้ในการเขียนต้นฉบับ เวอร์ชันล่าสุดของภาษาคือ v2
rules_version = '2';
service cloud.firestore {
...
}
ถ้าไม่ได้ระบุคำสั่ง rules_version
กฎของคุณจะได้รับการประเมินโดยใช้เครื่องมือ v1
บริการ
การประกาศ service
จะกำหนดผลิตภัณฑ์หรือบริการของ Firebase ที่กฎของคุณมีผล คุณสามารถรวมการประกาศ service
ได้เพียงรายการเดียวต่อไฟล์ต้นทาง
Cloud Firestore
service cloud.firestore {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
การจัดเก็บเมฆ
service firebase.storage {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
หากคุณกำหนดกฎสำหรับทั้ง Cloud Firestore และ Cloud Storage โดยใช้ Firebase CLI คุณจะต้องรักษากฎเหล่านั้นในไฟล์แยกกัน
จับคู่
บล็อก match
จะประกาศรูปแบบ path
ที่จับคู่กับเส้นทางสำหรับการดำเนินการที่ร้องขอ ( request.path
ที่เข้ามา) เนื้อความของ match
ต้องมีอย่างน้อยหนึ่งบล็อกการ match
ที่ซ้อน allow
หรือการประกาศ function
เส้นทางในบล็อก match
ที่ซ้อนกันจะสัมพันธ์กับเส้นทางในบล็อก match
หลัก
รูปแบบ path
เป็นชื่อที่เหมือนไดเร็กทอรีซึ่งอาจมีตัวแปรหรือสัญลักษณ์แทน รูปแบบ path
ช่วยให้สามารถจับคู่เส้นทางเดียวและหลายเส้นทางได้ ตัวแปรใดๆ ที่เชื่อมโยงใน path
จะมองเห็นได้ภายในขอบเขต match
หรือขอบเขตที่ซ้อนกันใดๆ ที่ path
ถูกประกาศ
การจับคู่กับรูปแบบ path
อาจเป็นบางส่วนหรือทั้งหมดก็ได้:
- ตรงกันบางส่วน: รูปแบบ
path
เป็นคำนำหน้าตรงกับrequest.path
- การจับคู่ที่สมบูรณ์: รูปแบบ
path
ตรงกับทั้งrequest.path
เมื่อจับคู่ สมบูรณ์ แล้ว กฎภายในบล็อกจะได้รับการประเมิน เมื่อทำการจับคู่ บางส่วน กฎ match
แบบซ้อนจะได้รับการทดสอบเพื่อดูว่า path
แบบซ้อนใดๆ จะทำการจับคู่ ให้สมบูรณ์ หรือไม่
กฎใน match
ที่สมบูรณ์ แต่ละรายการจะได้รับการประเมินเพื่อพิจารณาว่าจะอนุญาตคำขอหรือไม่ หากกฎการจับคู่ใดๆ ให้สิทธิ์เข้าถึง คำขอนั้นจะได้รับอนุญาต หากไม่มีกฎที่ตรงกันให้สิทธิ์การเข้าถึง คำขอจะถูกปฏิเสธ
// Given request.path == /example/hello/nested/path the following
// declarations indicate whether they are a partial or complete match and
// the value of any variables visible within the scope.
service firebase.storage {
// Partial match.
match /example/{singleSegment} { // `singleSegment` == 'hello'
allow write; // Write rule not evaluated.
// Complete match.
match /nested/path { // `singleSegment` visible in scope.
allow read; // Read rule is evaluated.
}
}
// Complete match.
match /example/{multiSegment=**} { // `multiSegment` == /hello/nested/path
allow read; // Read rule is evaluated.
}
}
ตามตัวอย่างด้านบน การประกาศ path
สนับสนุนตัวแปรต่อไปนี้:
- ไวด์การ์ดกลุ่มเดียว: ตัวแปรไวด์การ์ดถูกประกาศในเส้นทางโดยล้อมตัวแปรไว้ในวงเล็บปีกกา:
{variable}
ตัวแปรนี้สามารถเข้าถึงได้ภายในคำสั่งการmatch
เป็นstring
- ไวด์การ์ดแบบเรียกซ้ำ: ไวลด์การ์ดแบบเรียกซ้ำหรือหลายเซกเมนต์จะจับคู่พาธหลายเซกเมนต์ที่หรือต่ำกว่าพาธ ไวด์การ์ดนี้ตรงกับเส้นทางทั้งหมดด้านล่างตำแหน่งที่ตั้งที่คุณตั้งไว้ คุณสามารถประกาศได้โดยเพิ่มสตริง
=**
ที่ส่วนท้ายของตัวแปรกลุ่มของคุณ:{variable=**}
ตัวแปรนี้สามารถเข้าถึงได้ภายในคำสั่งmatch
เป็นวัตถุpath
อนุญาต
บล็อก match
ประกอบด้วยคำสั่ง allow
ตั้งแต่หนึ่งคำสั่งขึ้นไป นี่คือกฎที่แท้จริงของคุณ คุณสามารถใช้กฎ allow
กับเมธอดอย่างน้อยหนึ่งเมธอด เงื่อนไขในคำสั่ง allow
ต้องประเมินเป็นจริงสำหรับ Cloud Firestore หรือ Cloud Storage เพื่อให้อนุญาตคำขอที่เข้ามา คุณยังสามารถเขียนคำสั่ง allow
โดยไม่มีเงื่อนไข เช่น allow read
ถ้าคำสั่ง allow
ไม่มีเงื่อนไข อย่างไรก็ตาม จะอนุญาตคำขอสำหรับวิธีการนั้นเสมอ
หากเป็นไปตามกฎ allow
ใดๆ สำหรับเมธอด คำขอจะได้รับอนุญาต นอกจากนี้ หากกฎที่กว้างกว่านี้ให้สิทธิ์การเข้าถึง กฎจะอนุญาตการเข้าถึงและไม่สนใจกฎที่ละเอียดกว่านี้ซึ่งอาจจำกัดการเข้าถึง
พิจารณาตัวอย่างต่อไปนี้ ซึ่งผู้ใช้สามารถอ่านหรือลบไฟล์ของตนเองได้ กฎที่ละเอียดยิ่งขึ้นจะอนุญาตให้เขียนได้ก็ต่อเมื่อผู้ใช้ที่ขอให้เขียนเป็นเจ้าของไฟล์และไฟล์นั้นเป็น PNG ผู้ใช้สามารถลบไฟล์ใดๆ ที่พาธย่อย — แม้ว่าจะไม่ใช่ PNG — เนื่องจากกฎก่อนหน้านี้อนุญาต
service firebase.storage {
// Allow the requestor to read or delete any resource on a path under the
// user directory.
match /users/{userId}/{anyUserFile=**} {
allow read, delete: if request.auth != null && request.auth.uid == userId;
}
// Allow the requestor to create or update their own images.
// When 'request.method' == 'delete' this rule and the one matching
// any path under the user directory would both match and the `delete`
// would be permitted.
match /users/{userId}/images/{imageId} {
// Whether to permit the request depends on the logical OR of all
// matched rules. This means that even if this rule did not explicitly
// allow the 'delete' the earlier rule would have.
allow write: if request.auth != null && request.auth.uid == userId && imageId.matches('*.png');
}
}
วิธี
คำสั่ง allow
แต่ละรายการมีวิธีการที่ให้สิทธิ์การเข้าถึงสำหรับคำขอขาเข้าของวิธีการเดียวกัน
วิธี | ประเภทของคำขอ |
---|---|
วิธีอำนวยความสะดวก | |
read | คำขออ่านประเภทใดก็ได้ |
write | คำขอเขียนประเภทใดก็ได้ |
วิธีการมาตรฐาน | |
get | อ่านคำขอสำหรับเอกสารหรือไฟล์เดียว |
list | อ่านคำขอสำหรับแบบสอบถามและคอลเลกชัน |
create | เขียนเอกสารหรือไฟล์ใหม่ |
update | เขียนไปยังเอกสารฐานข้อมูลที่มีอยู่หรืออัปเดตข้อมูลเมตาของไฟล์ |
delete | ลบข้อมูล |
คุณไม่สามารถซ้อนทับวิธีการอ่านในบล็อก match
เดียวกันหรือวิธีการเขียนที่ขัดแย้งกันในการประกาศ path
เดียวกัน
ตัวอย่างเช่น กฎต่อไปนี้จะล้มเหลว:
service bad.example {
match /rules/with/overlapping/methods {
// This rule allows reads to all authenticated users
allow read: if request.auth != null;
match another/subpath {
// This secondary, more specific read rule causes an error
allow get: if request.auth != null && request.auth.uid == "me";
// Overlapping write methods in the same path cause an error as well
allow write: if request.auth != null;
allow create: if request.auth != null && request.auth.uid == "me";
}
}
}
การทำงาน
เมื่อกฎความปลอดภัยของคุณซับซ้อนมากขึ้น คุณอาจต้องการรวมชุดเงื่อนไขในฟังก์ชันที่คุณใช้ซ้ำได้ในชุดกฎของคุณ กฎความปลอดภัยรองรับฟังก์ชันแบบกำหนดเอง ไวยากรณ์สำหรับฟังก์ชันแบบกำหนดเองจะคล้ายกับ JavaScript แต่ฟังก์ชันกฎความปลอดภัยเขียนด้วยภาษาเฉพาะโดเมนซึ่งมีข้อจำกัดที่สำคัญบางประการ:
- ฟังก์ชันสามารถมีคำสั่ง
return
เดียวเท่านั้น ไม่สามารถมีตรรกะเพิ่มเติมใดๆ ตัวอย่างเช่น พวกเขาไม่สามารถดำเนินการวนซ้ำหรือเรียกใช้บริการภายนอกได้ - ฟังก์ชันสามารถเข้าถึงฟังก์ชันและตัวแปรโดยอัตโนมัติจากขอบเขตที่กำหนดไว้ ตัวอย่างเช่น ฟังก์ชันที่กำหนดภายในขอบเขต
service cloud.firestore
มีสิทธิ์เข้าถึงตัวแปรresource
และฟังก์ชันในตัว เช่นget()
และexists()
- ฟังก์ชันอาจเรียกใช้ฟังก์ชันอื่นแต่ไม่สามารถเรียกซ้ำได้ ความลึกของ call stack ทั้งหมดจำกัดอยู่ที่ 20
- ในกฎเวอร์ชัน
v2
ฟังก์ชันสามารถกำหนดตัวแปรโดยใช้คำหลักlet
ฟังก์ชันสามารถมีได้มากถึง 10 การรวม let แต่ต้องลงท้ายด้วยคำสั่ง 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();
}
}
}
นี่คือตัวอย่างที่แสดงอาร์กิวเมนต์ของฟังก์ชันและการมอบหมายงาน คำสั่งการมอบหมายงานให้ต้องคั่นด้วยเครื่องหมายอัฒภาค
function isAuthorOrAdmin(userId, article) {
let isAuthor = article.author == userId;
let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
return isAuthor || isAdmin;
}
โปรดทราบว่าการกำหนด isAdmin
บังคับใช้การค้นหาคอลเลกชันของผู้ดูแลระบบอย่างไร สำหรับการประเมินแบบขี้เกียจโดยไม่ต้องมีการค้นหาที่ไม่จำเป็น ให้ใช้ประโยชน์จากลักษณะการลัดวงจรของ &&
(AND) และ ||
(หรือ) การเปรียบเทียบเพื่อเรียกฟังก์ชันที่สองเฉพาะในกรณีที่ isAuthor
ถูกแสดงว่าเป็นจริง (สำหรับ &&
การเปรียบเทียบ) หรือเท็จ (สำหรับ ||
การเปรียบเทียบ)
function isAdmin(userId) {
return exists(/databases/$(database)/documents/admins/$(userId));
}
function isAuthorOrAdmin(userId, article) {
let isAuthor = article.author == userId;
// `||` is short-circuiting; isAdmin called only if isAuthor == false.
return isAuthor || isAdmin(userId);
}
การใช้ฟังก์ชันในกฎความปลอดภัยทำให้รักษาได้มากขึ้นตามความซับซ้อนของกฎที่เพิ่มขึ้น
ฐานข้อมูลเรียลไทม์
ตามที่ระบุไว้ข้างต้น กฎของฐานข้อมูลเรียลไทม์มีองค์ประกอบพื้นฐานสามประการ: ตำแหน่งฐานข้อมูลที่เป็นมิเรอร์ของโครงสร้าง JSON ของฐานข้อมูล ประเภทคำขอ และเงื่อนไขการให้สิทธิ์การเข้าถึง
ตำแหน่งฐานข้อมูล
โครงสร้างกฎของคุณควรเป็นไปตามโครงสร้างของข้อมูลที่คุณจัดเก็บไว้ในฐานข้อมูลของคุณ ตัวอย่างเช่น ในแอปแชทที่มีรายการข้อความ คุณอาจมีข้อมูลที่มีลักษณะดังนี้:
{
"messages": {
"message0": {
"content": "Hello",
"timestamp": 1405704370369
},
"message1": {
"content": "Goodbye",
"timestamp": 1405704395231
},
...
}
}
กฎของคุณควรสะท้อนถึงโครงสร้างนั้น ตัวอย่างเช่น:
{
"rules": {
"messages": {
"$message": {
// only messages from the last ten minutes can be read
".read": "data.child('timestamp').val() > (now - 600000)",
// new messages must have a string content and a number timestamp
".validate": "newData.hasChildren(['content', 'timestamp']) &&
newData.child('content').isString() &&
newData.child('timestamp').isNumber()"
}
}
}
}
ตามตัวอย่างด้านบน กฎฐานข้อมูลเรียลไทม์สนับสนุนตัวแปร $location
เพื่อจับคู่ส่วนเส้นทาง ใช้ $
คำนำหน้าส่วนเส้นทางของคุณเพื่อจับคู่กฎของคุณกับโหนดย่อยตามเส้นทาง
{
"rules": {
"rooms": {
// This rule applies to any child of /rooms/, the key for each room id
// is stored inside $room_id variable for reference
"$room_id": {
"topic": {
// The room's topic can be changed if the room id has "public" in it
".write": "$room_id.contains('public')"
}
}
}
}
}
คุณยังสามารถใช้ $variable
ไปกับชื่อเส้นทางคงที่
{
"rules": {
"widget": {
// a widget can have a title or color attribute
"title": { ".validate": true },
"color": { ".validate": true },
// but no other child paths are allowed
// in this case, $other means any key excluding "title" and "color"
"$other": { ".validate": false }
}
}
}
วิธี
ใน Realtime Database มีกฎสามประเภท กฎสองประเภทเหล่านี้ — read
และ write
— ใช้กับวิธีการของคำขอที่เข้ามา ประเภทกฎ validate
ใช้โครงสร้างข้อมูลและตรวจสอบความถูกต้องของรูปแบบและเนื้อหาของข้อมูล กฎเรียกใช้ .validate
หลังจากตรวจสอบว่ากฎ .write
ให้สิทธิ์การเข้าถึง
ประเภทกฎ | |
---|---|
.อ่าน | อธิบายว่าผู้ใช้สามารถอ่านข้อมูลได้หรือไม่และเมื่อใด |
.เขียน | อธิบายว่าอนุญาตให้เขียนข้อมูลได้หรือไม่และเมื่อใด |
.ตรวจสอบความถูกต้อง | กำหนดค่าที่จัดรูปแบบอย่างถูกต้องจะมีลักษณะอย่างไร ไม่ว่าจะมีแอตทริบิวต์ย่อยและประเภทข้อมูลหรือไม่ |
ตามค่าเริ่มต้น หากไม่มีกฎอนุญาต การเข้าถึงที่เส้นทางจะถูกปฏิเสธ
สภาพอาคาร
Cloud Firestore
เงื่อนไขคือนิพจน์บูลีนที่กำหนดว่าควรอนุญาตหรือปฏิเสธการดำเนินการเฉพาะ ตัวแปร request
และ resource
จัดเตรียมบริบทสำหรับเงื่อนไขเหล่านั้น
ตัวแปร request
ตัวแปร request
ประกอบด้วยฟิลด์ต่อไปนี้และข้อมูลที่สอดคล้องกัน:
request.auth
JSON Web Token (JWT) ที่มีข้อมูลรับรองการตรวจสอบสิทธิ์จาก Firebase Authentication โทเค็น auth
รับรองความถูกต้องมีชุดของการอ้างสิทธิ์มาตรฐานและการอ้างสิทธิ์แบบกำหนดเองใดๆ ที่คุณสร้างขึ้นผ่านการตรวจสอบสิทธิ์ของ Firebase เรียนรู้เพิ่มเติมเกี่ยวกับ กฎความปลอดภัยของ Firebase และการตรวจสอบสิทธิ์
request.method
request.method
อาจเป็นวิธีมาตรฐานหรือวิธีกำหนดเองก็ได้ วิธีการ read
และ write
ที่สะดวกยังมีอยู่เพื่อลดความซับซ้อนของกฎการเขียนที่ใช้กับวิธีมาตรฐานแบบอ่านอย่างเดียวหรือเขียนอย่างเดียวทั้งหมดตามลำดับ
request.params
request.params
รวมข้อมูลใดๆ ที่ไม่เกี่ยวข้องกับ request.resource
เป็นพิเศษ ซึ่งอาจเป็นประโยชน์สำหรับการประเมิน ในทางปฏิบัติ แผนที่นี้ควรว่างเปล่าสำหรับวิธีการมาตรฐานทั้งหมด และควรมีข้อมูลที่ไม่ใช่ทรัพยากรสำหรับวิธีการที่กำหนดเอง บริการจะต้องระมัดระวังที่จะไม่เปลี่ยนชื่อหรือแก้ไขประเภทของคีย์และค่าใดๆ ที่แสดงเป็นพารามิเตอร์
request.path
request.path
เป็นเส้นทางสำหรับ resource
เป้าหมาย เส้นทางสัมพันธ์กับบริการ ส่วนเส้นทางที่มีอักขระที่ปลอดภัยที่ไม่ใช่ URL เช่น /
ถูกเข้ารหัส URL
ตัวแปร resource
resource
คือค่าปัจจุบันภายในบริการที่แสดงเป็นแผนผังของคู่คีย์-ค่า การอ้างอิง resource
ภายในเงื่อนไขจะทำให้อ่านค่าจากบริการได้มากที่สุดหนึ่งครั้ง การค้นหานี้จะนับรวมกับโควต้าที่เกี่ยวข้องกับบริการสำหรับทรัพยากร สำหรับคำ get
resource
จะนับรวมในโควต้าเมื่อปฏิเสธเท่านั้น
ตัวดำเนินการและลำดับความสำคัญของตัวดำเนินการ
ใช้ตารางด้านล่างเป็นข้อมูลอ้างอิงสำหรับตัวดำเนินการและลำดับความสำคัญที่เกี่ยวข้องในกฎสำหรับ Cloud Firestore และ Cloud Storage
กำหนดนิพจน์ตามอำเภอใจ a
และ b
ฟิลด์ f
และดัชนี i
โอเปอเรเตอร์ | คำอธิบาย | ความเชื่อมโยง |
---|---|---|
a[i] a() af | ดัชนี การโทร การเข้าถึงสนาม | ซ้ายไปขวา | !a -a | การปฏิเสธแบบเอกนารี | จากขวาไปซ้าย |
a/ba%ba*b | ตัวดำเนินการคูณ | ซ้ายไปขวา |
a+b ab | ตัวดำเนินการเสริม | ซ้ายไปขวา |
a>ba>=ba | ตัวดำเนินการเชิงสัมพันธ์ | ซ้ายไปขวา |
a in b | มีอยู่ในรายการหรือแผนที่ | ซ้ายไปขวา |
a is type | การเปรียบเทียบประเภท โดยที่ type สามารถเป็น bool, int, float, number, string, list, map, timestamp, Duration, Path หรือ latlng | ซ้ายไปขวา |
a==ba!=b | ตัวดำเนินการเปรียบเทียบ | ซ้ายไปขวา | a && b | เงื่อนไขและ | ซ้ายไปขวา |
a || b | เงื่อนไขหรือ | ซ้ายไปขวา |
a ? true_value : false_value | การแสดงออกที่ประกอบไปด้วย | ซ้ายไปขวา |
การจัดเก็บเมฆ
เงื่อนไขคือนิพจน์บูลีนที่กำหนดว่าควรอนุญาตหรือปฏิเสธการดำเนินการเฉพาะ ตัวแปร request
และ resource
จัดเตรียมบริบทสำหรับเงื่อนไขเหล่านั้น
ตัวแปร request
ตัวแปร request
ประกอบด้วยฟิลด์ต่อไปนี้และข้อมูลที่สอดคล้องกัน:
request.auth
JSON Web Token (JWT) ที่มีข้อมูลรับรองการตรวจสอบสิทธิ์จาก Firebase Authentication โทเค็น auth
รับรองความถูกต้องมีชุดของการอ้างสิทธิ์มาตรฐานและการอ้างสิทธิ์แบบกำหนดเองใดๆ ที่คุณสร้างขึ้นผ่านการตรวจสอบสิทธิ์ของ Firebase เรียนรู้เพิ่มเติมเกี่ยวกับ กฎความปลอดภัยของ Firebase และการตรวจสอบสิทธิ์
request.method
request.method
อาจเป็นวิธีมาตรฐานหรือวิธีกำหนดเองก็ได้ วิธีการ read
และ write
ที่สะดวกยังมีอยู่เพื่อลดความซับซ้อนของกฎการเขียนที่ใช้กับวิธีมาตรฐานแบบอ่านอย่างเดียวหรือเขียนอย่างเดียวทั้งหมดตามลำดับ
request.params
request.params
รวมข้อมูลใดๆ ที่ไม่เกี่ยวข้องกับ request.resource
เป็นพิเศษ ซึ่งอาจเป็นประโยชน์สำหรับการประเมิน ในทางปฏิบัติ แผนที่นี้ควรว่างเปล่าสำหรับวิธีการมาตรฐานทั้งหมด และควรมีข้อมูลที่ไม่ใช่ทรัพยากรสำหรับวิธีการแบบกำหนดเอง บริการจะต้องระมัดระวังที่จะไม่เปลี่ยนชื่อหรือแก้ไขประเภทของคีย์และค่าใดๆ ที่แสดงเป็นพารามิเตอร์
request.path
request.path
เป็นเส้นทางสำหรับ resource
เป้าหมาย เส้นทางสัมพันธ์กับบริการ ส่วนเส้นทางที่มีอักขระที่ปลอดภัยที่ไม่ใช่ URL เช่น /
ถูกเข้ารหัส URL
ตัวแปร resource
resource
คือค่าปัจจุบันภายในบริการที่แสดงเป็นแผนผังของคู่คีย์-ค่า การอ้างอิง resource
ภายในเงื่อนไขจะทำให้อ่านค่าจากบริการได้มากที่สุดหนึ่งครั้ง การค้นหานี้จะนับรวมกับโควต้าที่เกี่ยวข้องกับบริการสำหรับทรัพยากร สำหรับคำ get
resource
จะนับรวมในโควต้าเมื่อปฏิเสธเท่านั้น
ตัวดำเนินการและลำดับความสำคัญของตัวดำเนินการ
ใช้ตารางด้านล่างเป็นข้อมูลอ้างอิงสำหรับตัวดำเนินการและลำดับความสำคัญที่เกี่ยวข้องในกฎสำหรับ Cloud Firestore และ Cloud Storage
กำหนดนิพจน์ตามอำเภอใจ a
และ b
ฟิลด์ f
และดัชนี i
โอเปอเรเตอร์ | คำอธิบาย | ความเชื่อมโยง |
---|---|---|
a[i] a() af | ดัชนี การโทร การเข้าถึงสนาม | ซ้ายไปขวา | !a -a | การปฏิเสธแบบเอกนารี | จากขวาไปซ้าย |
a/ba%ba*b | ตัวดำเนินการคูณ | ซ้ายไปขวา |
a+b ab | ตัวดำเนินการเสริม | ซ้ายไปขวา |
a>ba>=ba | ตัวดำเนินการเชิงสัมพันธ์ | ซ้ายไปขวา |
a in b | มีอยู่ในรายการหรือแผนที่ | ซ้ายไปขวา |
a is type | การเปรียบเทียบประเภท โดยที่ type สามารถเป็น bool, int, float, number, string, list, map, timestamp, Duration, Path หรือ latlng | ซ้ายไปขวา |
a==ba!=b | ตัวดำเนินการเปรียบเทียบ | ซ้ายไปขวา | a && b | เงื่อนไขและ | ซ้ายไปขวา |
a || b | เงื่อนไขหรือ | ซ้ายไปขวา |
a ? true_value : false_value | การแสดงออกที่ประกอบไปด้วย | ซ้ายไปขวา |
ฐานข้อมูลเรียลไทม์
เงื่อนไขคือนิพจน์บูลีนที่กำหนดว่าควรอนุญาตหรือปฏิเสธการดำเนินการเฉพาะ คุณสามารถกำหนดเงื่อนไขเหล่านั้นใน Realtime Database Rules ได้ด้วยวิธีต่อไปนี้
ตัวแปรที่กำหนดไว้ล่วงหน้า
มีตัวแปรที่กำหนดไว้ล่วงหน้าที่เป็นประโยชน์จำนวนมากซึ่งสามารถเข้าถึงได้ภายในคำจำกัดความของกฎ นี่คือบทสรุปสั้น ๆ ของแต่ละ:
ตัวแปรที่กำหนดไว้ล่วงหน้า | |
---|---|
ตอนนี้ | เวลาปัจจุบันเป็นมิลลิวินาทีตั้งแต่ยุค Linux ซึ่งใช้งานได้ดีเป็นพิเศษสำหรับการตรวจสอบการประทับเวลาที่สร้างด้วย firebase.database.ServerValue.TIMESTAMP ของ SDK |
ราก | RuleDataSnapshot ที่แสดงเส้นทางรูทในฐานข้อมูล Firebase ตามที่มีอยู่ก่อนที่จะพยายามดำเนินการ |
ข้อมูลใหม่ | RuleDataSnapshot ที่แสดงข้อมูลตามที่จะมีอยู่หลังจากการพยายามดำเนินการ ซึ่งรวมถึงข้อมูลใหม่ที่กำลังเขียนและข้อมูลที่มีอยู่ |
ข้อมูล | RuleDataSnapshot ที่แสดงข้อมูลตามที่มีอยู่ก่อนการดำเนินการที่พยายาม |
$ ตัวแปร | เส้นทางตัวแทนที่ใช้เพื่อแสดงรหัสและคีย์ลูกแบบไดนามิก |
รับรองความถูกต้อง | แสดงเพย์โหลดโทเค็นของผู้ใช้ที่ผ่านการรับรองความถูกต้อง |
ตัวแปรเหล่านี้สามารถใช้ได้ทุกที่ในกฎของคุณ ตัวอย่างเช่น กฎความปลอดภัยด้านล่างรับรองว่าข้อมูลที่เขียนไปยังโหนด /foo/
ต้องเป็นสตริงที่มีความยาวน้อยกว่า 100 อักขระ:
{ "rules": { "foo": { // /foo is readable by the world ".read": true, // /foo is writable by the world ".write": true, // data written to /foo must be a string less than 100 characters ".validate": "newData.isString() && newData.val().length < 100" } } }
กฎตามข้อมูล
ข้อมูลใดๆ ในฐานข้อมูลของคุณสามารถนำมาใช้ในกฎของคุณได้ เมื่อใช้ตัวแปรที่กำหนดไว้ล่วงหน้า root
, data
และ newData
คุณจะสามารถเข้าถึงพาธใดๆ ก็ได้ตามที่ปรากฏก่อนหรือหลังเหตุการณ์เขียน
ลองพิจารณาตัวอย่างนี้ ซึ่งอนุญาตการดำเนินการเขียนตราบเท่าที่ค่าของโหนด /allow_writes/
เป็น true
โหนดพาเรนต์ไม่มีชุดแฟล็ก readOnly
และมีลูกชื่อ foo
ในข้อมูลที่เขียนใหม่:
".write": "root.child('allow_writes').val() === true && !data.parent().child('readOnly').exists() && newData.child('foo').exists()"
กฎตามแบบสอบถาม
แม้ว่าคุณจะไม่สามารถใช้กฎเป็นตัวกรองได้ แต่คุณสามารถจำกัดการเข้าถึงข้อมูลชุดย่อยได้โดยใช้พารามิเตอร์การค้นหาในกฎของคุณ ใช้ query.
นิพจน์ในกฎของคุณเพื่อให้สิทธิ์การเข้าถึงแบบอ่านหรือเขียนตามพารามิเตอร์การค้นหา
ตัวอย่างเช่น กฎตามคิวรีต่อไปนี้ใช้ กฎความปลอดภัยตามผู้ใช้ และกฎตามคิวรีเพื่อจำกัดการเข้าถึงข้อมูลในคอลเล็กชัน baskets
ให้เฉพาะตะกร้าสินค้าที่ผู้ใช้ที่ใช้งานอยู่เป็นเจ้าของเท่านั้น:
"baskets": {
".read": "auth.uid !== null &&
query.orderByChild === 'owner' &&
query.equalTo === auth.uid" // restrict basket access to owner of basket
}
ข้อความค้นหาต่อไปนี้ซึ่งมีพารามิเตอร์ข้อความค้นหาในกฎจะสำเร็จ:
db.ref("baskets").orderByChild("owner")
.equalTo(auth.currentUser.uid)
.on("value", cb) // Would succeed
อย่างไรก็ตาม ข้อความค้นหาที่ไม่มีพารามิเตอร์ในกฎจะล้มเหลวโดยมีข้อผิดพลาด PermissionDenied
:
db.ref("baskets").on("value", cb) // Would fail with PermissionDenied
คุณยังสามารถใช้กฎตามคิวรีเพื่อจำกัดจำนวนข้อมูลที่ไคลเอนต์ดาวน์โหลดผ่านการดำเนินการอ่าน
ตัวอย่างเช่น กฎต่อไปนี้จำกัดการเข้าถึงการอ่านเฉพาะผลลัพธ์ 1,000 รายการแรกของข้อความค้นหา โดยเรียงลำดับตามลำดับความสำคัญ:
messages: {
".read": "query.orderByKey &&
query.limitToFirst <= 1000"
}
// Example queries:
db.ref("messages").on("value", cb) // Would fail with PermissionDenied
db.ref("messages").limitToFirst(1000)
.on("value", cb) // Would succeed (default order by key)
query.
ต่อไปนี้ นิพจน์มีอยู่ในกฎความปลอดภัยของฐานข้อมูลแบบเรียลไทม์
นิพจน์กฎตามแบบสอบถาม | ||
---|---|---|
การแสดงออก | พิมพ์ | คำอธิบาย |
แบบสอบถาม orderByKey แบบสอบถาม orderByPriority แบบสอบถาม orderByValue | บูลีน | เป็นจริงสำหรับข้อความค้นหาที่เรียงลำดับตามคีย์ ลำดับความสำคัญ หรือค่า เป็นอย่างอื่น |
สอบถาม.orderByChild | สตริง โมฆะ | ใช้สตริงเพื่อแสดงเส้นทางสัมพัทธ์ไปยังโหนดย่อย ตัวอย่างเช่น query.orderByChild === "address/zip" หากคิวรีไม่ได้เรียงลำดับตามโหนดย่อย ค่านี้จะเป็นค่าว่าง |
แบบสอบถาม.startAt แบบสอบถามสิ้นสุดที่ แบบสอบถามเท่ากับ | สตริง ตัวเลข บูลีน โมฆะ | ดึงขอบเขตของแบบสอบถามที่กำลังดำเนินการ หรือคืนค่า null หากไม่มีชุดขอบเขต |
แบบสอบถาม.limitToFirst แบบสอบถาม.limitToLast | ตัวเลข โมฆะ | ดึงค่าขีดจำกัดของคิวรีที่กำลังดำเนินการ หรือคืนค่า null หากไม่มีการตั้งค่าขีดจำกัด |
ผู้ประกอบการ
กฎฐานข้อมูลเรียลไทม์รองรับ ตัวดำเนินการ จำนวนหนึ่งที่คุณสามารถใช้เพื่อรวมตัวแปรในคำสั่งเงื่อนไข ดูรายชื่อ ตัวดำเนินการทั้งหมดในเอกสารอ้างอิง
การสร้างเงื่อนไข
เงื่อนไขที่แท้จริงของคุณจะแตกต่างกันไปตามการเข้าถึงที่คุณต้องการให้สิทธิ์ กฎจงใจให้ความยืดหยุ่นในระดับมหาศาล ดังนั้นกฎของแอปของคุณจึงอาจเรียบง่ายหรือซับซ้อนตามที่คุณต้องการในท้ายที่สุด
สำหรับคำแนะนำบางประการในการสร้างกฎง่ายๆ ที่พร้อมใช้งานจริง โปรดดู กฎความปลอดภัยพื้นฐาน