ความปลอดภัยอาจเป็นหนึ่งในที่ซับซ้อนที่สุดของปริศนาการพัฒนาแอป ในแอปพลิเคชันส่วนใหญ่ นักพัฒนาแอปต้องสร้างและเรียกใช้เซิร์ฟเวอร์ที่จัดการการตรวจสอบสิทธิ์ (ผู้ใช้เป็นใคร) และการให้สิทธิ์ (สิ่งที่ผู้ใช้ทําได้)
Firebase Security Rules นำเลเยอร์กลาง (เซิร์ฟเวอร์) ออกและให้คุณระบุเส้นทางแบบอิงตามเส้นทางได้ สิทธิ์สำหรับลูกค้าที่เชื่อมต่อกับข้อมูลของคุณโดยตรง ใช้คู่มือนี้เพื่อ ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีใช้กฎกับคำขอที่เข้ามาใหม่
เลือกผลิตภัณฑ์เพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับกฎ
Cloud Firestore
โครงสร้างพื้นฐาน
Firebase Security Rules ใน 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
ซึ่งมีเงื่อนไขที่อนุญาตคําขอหากประเมินค่าเป็น "จริง"
กฎความปลอดภัยเวอร์ชัน 2
ในเดือนพฤษภาคม 2019 กฎความปลอดภัย Firebase เวอร์ชัน 2 พร้อมให้ใช้งานแล้ว กฎเวอร์ชัน 2 จะเปลี่ยนลักษณะการทำงานของ recursive
ไวลด์การ์ด {name=**}
คุณต้องใช้เวอร์ชัน 2 หากมีแผนที่จะ
ใช้การค้นหากลุ่มคอลเล็กชัน คุณต้องเลือกใช้
เวอร์ชัน 2 โดยทำให้ rules_version = '2';
เป็นบรรทัดแรกในการรักษาความปลอดภัยของคุณ
กฎ:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
เส้นทางที่ตรงกัน
ข้อความที่ตรงกันทั้งหมดควรชี้ไปยังเอกสาร ไม่ใช่คอลเล็กชัน การแข่งขัน
สามารถชี้ไปยังเอกสารที่เฉพาะเจาะจงได้ เช่น ใน match /cities/SF
หรือใช้ไวลด์การ์ด
เพื่อชี้ไปยังเอกสารในเส้นทางที่ระบุ เช่น match /cities/{city}
ในตัวอย่างด้านบน คำสั่งจับคู่จะใช้ไวยากรณ์ไวลด์การ์ด {city}
กฎนี้จะมีผลกับเอกสารในคอลเล็กชัน cities
เช่น
/cities/SF
หรือ/cities/NYC
เมื่อนิพจน์ allow
ในคำสั่งจับคู่
ประเมินแล้ว ตัวแปร city
จะเปลี่ยนเป็นชื่อเอกสารของเมือง
เช่น SF
หรือ NYC
คอลเล็กชันย่อยที่ตรงกัน
ข้อมูลใน 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 (ไม่ได้รับอนุญาต&r; |
จำนวนนิพจน์สูงสุดที่ประเมินต่อคำขอ | 1,000 ราย |
ขนาดสูงสุดของชุดกฎ | ชุดกฎต้องเป็นไปตามขีดจํากัดขนาด 2 ข้อต่อไปนี้
|
Cloud Storage
โครงสร้างพื้นฐาน
Firebase Security Rules ใน 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
ซึ่งมีเงื่อนไขที่อนุญาต หากประเมินเป็น "จริง"
เส้นทางที่ตรงกัน
Cloud Storage Security Rules match
เส้นทางของไฟล์ที่ใช้เข้าถึงไฟล์
Cloud Storage กฎอาจเป็นmatch
เส้นทางที่ตรงกันทุกประการหรือเส้นทางไวลด์การ์ด และกฎยังซ้อนกันได้อีกด้วย หากไม่มีกฎที่ตรงกันที่อนุญาตเมธอดคำขอ หรือ
ประเมินได้เป็น false
คำขอถูกปฏิเสธ
เหมือนกันทุกประการ
// Exact match for "images/profilePhoto.png" match /images/profilePhoto.png { allow write: if <condition>; } // Exact match for "images/croppedProfilePhoto.png" match /images/croppedProfilePhoto.png { allow write: if <other_condition>; }
รายการที่ตรงกันที่ซ้อนกัน
// Partial match for files that start with "images" match /images { // Exact match for "images/profilePhoto.png" match /profilePhoto.png { allow write: if <condition>; } // Exact match for "images/croppedProfilePhoto.png" match /croppedProfilePhoto.png { allow write: if <other_condition>; } }
การจับคู่ไวลด์การ์ด
นอกจากนี้ยังใช้กฎเพื่อmatch
รูปแบบโดยใช้ไวลด์การ์ดได้ด้วย ไวลด์การ์ดคือ
ตัวแปรที่มีชื่อซึ่งแสดงสตริงเดียว เช่น
profilePhoto.png
หรือกลุ่มเส้นทางหลายกลุ่ม เช่น
images/profilePhoto.png
ไวลด์การ์ดสร้างขึ้นโดยการใส่วงเล็บปีกการอบชื่อไวลด์การ์ด เช่น
{string}
คุณสามารถประกาศไวลด์การ์ดของกลุ่มหลายกลุ่มได้โดยการเพิ่ม =**
ลงในส่วน
ชื่อไวลด์การ์ด เช่น {path=**}
:
// Partial match for files that start with "images" match /images { // Exact match for "images/*" // e.g. images/profilePhoto.png is matched match /{imageId} { // This rule only matches a single path segment (*) // imageId is a string that contains the specific segment matched allow read: if <condition>; } // Exact match for "images/**" // e.g. images/users/user:12345/profilePhoto.png is matched // images/profilePhoto.png is also matched! match /{allImages=**} { // This rule matches one or more path segments (**) // allImages is a path that contains all segments matched allow read: if <other_condition>; } }
หากมีกฎหลายข้อตรงกับไฟล์ ผลลัพธ์จะเป็น OR
ของผลลัพธ์ทั้งหมด
และการประเมินกฎ กล่าวคือ หากกฎใดตรงกับไฟล์ประเมินผลเป็น true
ผลลัพธ์คือ true
ในกฎข้างต้น ไฟล์ "images/profilePhoto.png" สามารถอ่านได้ในกรณีต่อไปนี้
condition
หรือ other_condition
ประเมินผลเป็น "จริง" ขณะที่ไฟล์
"images/users/user:12345/profilePhoto.png" จะขึ้นอยู่กับผลลัพธ์ของ
other_condition
อ้างอิงตัวแปรไวลด์การ์ดได้จากภายในไฟล์ที่ระบุ match
ชื่อหรือเส้นทางการให้สิทธิ์:
// Another way to restrict the name of a file match /images/{imageId} { allow read: if imageId == "profilePhoto.png"; }
Cloud Storage Security Rules จะไม่ทํางานแบบซ้อนทับ และระบบจะประเมินกฎก็ต่อเมื่อเส้นทางคําขอตรงกับเส้นทางที่มีกฎที่ระบุ
ขอรับการประเมิน
ระบบจะประเมินการอัปโหลด ดาวน์โหลด การเปลี่ยนแปลงข้อมูลเมตา และการลบโดยใช้
ส่งเงินจำนวน request
ไปยัง Cloud Storage แล้ว ตัวแปร request
ประกอบด้วยค่า
เส้นทางไฟล์ที่ดำเนินการตามคำขอ เวลาที่คำขอ
ที่ได้รับ และค่า resource
ใหม่หากคำขอเป็นการเขียน ส่วนหัว HTTP
และสถานะการตรวจสอบสิทธิ์รวมอยู่ด้วย
ออบเจ็กต์ request
ยังมีรหัสที่ไม่ซ้ำกันของผู้ใช้และ
เพย์โหลด Firebase Authentication ในออบเจ็กต์ request.auth
ซึ่งจะ
ซึ่งอธิบายเพิ่มเติมในการตรวจสอบสิทธิ์
ของเอกสาร
รายการที่พักทั้งหมดในออบเจ็กต์ request
แสดงอยู่ด้านล่าง
พร็อพเพอร์ตี้ | ประเภท | คำอธิบาย |
---|---|---|
auth |
แมป<สตริง, สตริง> | เมื่อผู้ใช้เข้าสู่ระบบ ให้ระบุ uid , รหัสที่ไม่ซ้ำกันของผู้ใช้ และ
token แผนที่แสดงการอ้างสิทธิ์ JWT Firebase Authentication รายการ มิฉะนั้น ระบบจะ
null |
params |
แมป<สตริง, สตริง> | แผนที่ที่มีพารามิเตอร์การค้นหาของคำขอ |
path |
เส้นทาง | path ที่แสดงเส้นทางที่มีการส่งคำขอ
แสดงเมื่อ |
resource |
แมป<สตริง, สตริง> | ค่าทรัพยากรใหม่ที่มีอยู่ในคําขอ write เท่านั้น
|
time |
การประทับเวลา | การประทับเวลาที่แสดงถึงเวลาของเซิร์ฟเวอร์ที่มีการประเมินคำขอ |
การประเมินทรัพยากร
เมื่อประเมินกฎ คุณควรประเมินข้อมูลเมตาของไฟล์ด้วย ถูกอัปโหลด ดาวน์โหลด แก้ไข หรือลบ ซึ่งทำให้คุณสามารถสร้าง และกฎที่ซับซ้อนและมีประสิทธิภาพซึ่งทำสิ่งต่างๆ เช่น อนุญาตเฉพาะไฟล์ที่มี เนื้อหาประเภทที่จะอัปโหลด หรือเฉพาะไฟล์ขนาดใหญ่กว่าขนาดที่กำหนด ลบแล้ว
Firebase Security Rules สำหรับ Cloud Storage ให้ข้อมูลเมตาของไฟล์ในออบเจ็กต์ resource
ซึ่งมีคู่คีย์/ค่าของข้อมูลเมตาที่แสดงในออบเจ็กต์ Cloud Storage ตรวจสอบพร็อพเพอร์ตี้เหล่านี้ได้ใน read
หรือ
write
คำขอเพื่อตรวจสอบความสมบูรณ์ของข้อมูล
ในคำขอ write
(เช่น การอัปโหลด อัปเดตข้อมูลเมตา และการลบ) ใน
นอกเหนือจากออบเจ็กต์ resource
ซึ่งมีข้อมูลเมตาของไฟล์
ที่มีอยู่ในเส้นทางคำขออยู่แล้ว คุณยังสามารถใช้
request.resource
ซึ่งมีข้อมูลเมตาบางส่วนของไฟล์
เขียนหากการเขียนได้รับอนุญาต คุณใช้ค่า 2 ค่านี้เพื่อตรวจสอบข้อมูล
ความสมบูรณ์หรือบังคับใช้ข้อจำกัดของแอปพลิเคชัน เช่น ประเภทไฟล์หรือขนาดไฟล์
รายการที่พักทั้งหมดในออบเจ็กต์ resource
แสดงอยู่ด้านล่าง
พร็อพเพอร์ตี้ | ประเภท | คำอธิบาย |
---|---|---|
name |
สตริง | ชื่อเต็มของออบเจ็กต์ |
bucket |
สตริง | ชื่อของที่เก็บข้อมูลที่ออบเจ็กต์นี้อยู่ |
generation |
int | Google Cloud Storage การสร้างออบเจ็กต์ของออบเจ็กต์นี้ |
metageneration |
int | Google Cloud Storage Metageneration ของออบเจ็กต์นี้ |
size |
int | ขนาดของออบเจ็กต์ในหน่วยไบต์ |
timeCreated |
การประทับเวลา | การประทับเวลาที่แสดงถึงเวลาที่สร้างออบเจ็กต์ |
updated |
การประทับเวลา | การประทับเวลาที่แสดงถึงเวลาที่อัปเดตออบเจ็กต์ครั้งล่าสุด |
md5Hash |
สตริง | แฮช MD5 ของออบเจ็กต์ |
crc32c |
สตริง | แฮช CRC32c ของออบเจ็กต์ |
etag |
สตริง | eTag ที่เชื่อมโยงกับออบเจ็กต์นี้ |
contentDisposition |
สตริง | การจัดการเนื้อหาที่เชื่อมโยงกับออบเจ็กต์นี้ |
contentEncoding |
สตริง | การเข้ารหัสเนื้อหาที่เชื่อมโยงกับออบเจ็กต์นี้ |
contentLanguage |
สตริง | ภาษาของเนื้อหาที่เชื่อมโยงกับออบเจ็กต์นี้ |
contentType |
สตริง | ประเภทเนื้อหาที่เชื่อมโยงกับออบเจ็กต์นี้ |
metadata |
แมป<สตริง, สตริง> | คู่คีย์/ค่าของข้อมูลเมตาที่กำหนดเองเพิ่มเติมที่นักพัฒนาซอฟต์แวร์ระบุ |
request.resource
มีข้อมูลทั้งหมดนี้ ยกเว้น generation
metageneration
, etag
, timeCreated
และ updated
ขีดจํากัดของกฎความปลอดภัย
โปรดคำนึงถึงขีดจำกัดต่อไปนี้เมื่อทำงานกับกฎความปลอดภัย
ขีดจำกัด | รายละเอียด |
---|---|
จำนวนสูงสุดคือ firestore.exists() และ
firestore.get() สายต่อคำขอ |
2 สำหรับคำขอเอกสารรายการเดียวและคำขอคำค้นหา การเกินขีดจำกัดนี้จะส่งผลให้เกิดข้อผิดพลาดสิทธิ์ถูกปฏิเสธ การเรียกการเข้าถึงเอกสารเดียวกันอาจถูกเก็บในแคช และการเรียกในแคช จะไม่นับรวมในขีดจำกัด |
ตัวอย่างแบบเต็ม
เมื่อนำทั้งหมดมารวมกัน คุณก็จะได้สร้างกฎตัวอย่างที่สมบูรณ์สำหรับรูปภาพหนึ่งๆ โซลูชันพื้นที่เก็บข้อมูล
service firebase.storage { match /b/{bucket}/o { match /images { // Cascade read to any image type at any path match /{allImages=**} { allow read; } // Allow write files to the path "images/*", subject to the constraints: // 1) File is less than 5MB // 2) Content type is an image // 3) Uploaded content type matches existing content type // 4) File name (stored in imageId wildcard variable) is less than 32 characters match /{imageId} { allow write: if request.resource.size < 5 * 1024 * 1024 && request.resource.contentType.matches('image/.*') && request.resource.contentType == resource.contentType && imageId.size() < 32 } } } }
Realtime Database
โครงสร้างพื้นฐาน
ใน Realtime Database Firebase Security Rules ประกอบด้วยนิพจน์ที่เหมือน JavaScript ที่มีอยู่ใน เอกสาร JSON
โดยจะใช้ไวยากรณ์ต่อไปนี้
{
"rules": {
"<<path>>": {
// Allow the request if the condition for each method is true.
".read": <<condition>>,
".write": <<condition>>,
".validate": <<condition>>
}
}
}
มีองค์ประกอบพื้นฐาน 3 อย่างในกฎดังนี้
- เส้นทาง: ตำแหน่งฐานข้อมูล การดำเนินการนี้จะมิเรอร์โครงสร้าง JSON ของฐานข้อมูลคุณ
- คำขอ: วิธีที่กฎใช้เพื่อให้สิทธิ์เข้าถึง กฎ
read
และwrite
ให้สิทธิ์การอ่านและเขียนอย่างกว้างขวาง ส่วนกฎvalidate
จะทำหน้าที่เป็นการตรวจสอบรองเพื่อให้สิทธิ์เข้าถึงตามข้อมูลขาเข้าหรือข้อมูลที่มีอยู่ - เงื่อนไข: เงื่อนไขที่อนุญาตคำขอเมื่อประเมินแล้วว่าเป็นจริง
วิธีใช้กฎกับเส้นทาง
ในภาษาRealtime Database จะมีการใช้ Rules ในระดับอะตอม ซึ่งหมายความว่ากฎที่ โหนดระดับบนสุดระดับสูงกว่าจะลบล้างกฎในโหนดย่อยที่ละเอียดยิ่งขึ้นและ กฎในโหนดที่ลึกกว่าไม่สามารถให้สิทธิ์เข้าถึงเส้นทางระดับบนสุด คุณ ไม่สามารถปรับแต่งหรือเพิกถอนการเข้าถึงในระดับที่ลึกกว่าในโครงสร้างฐานข้อมูล คุณได้ให้สิทธิ์สำหรับเส้นทางหลักรายการใดรายการหนึ่งแล้ว
โดยพิจารณากฎต่อไปนี้
{ "rules": { "foo": { // allows read to /foo/* ".read": "data.child('baz').val() === true", "bar": { // ignored, since read was allowed already ".read": false } } } }
โครงสร้างการรักษาความปลอดภัยนี้ช่วยให้อ่าน /bar/
ได้ตั้งแต่เมื่อใด
/foo/
มีย่อย baz
ที่มีค่า true
กฎ ".read": false
ในส่วน /foo/bar/
จะไม่มีผลที่นี่ เนื่องจากเส้นทางย่อยไม่สามารถเพิกถอนสิทธิ์เข้าถึงได้
แม้ว่าอาจจะดูไม่สมเหตุสมผลในทันที แต่นี่เป็นส่วนที่มีประสิทธิภาพของ ภาษาของกฎ และช่วยให้มีการใช้สิทธิ์การเข้าถึงที่ซับซ้อนมาก โดยใช้ความพยายามเพียงเล็กน้อย ซึ่งจะเป็นประโยชน์อย่างยิ่งสำหรับการรักษาความปลอดภัยตามผู้ใช้
อย่างไรก็ตาม กฎ .validate
รายการจะไม่เรียงซ้อนกัน กฎการตรวจสอบทั้งหมด
การเขียนจะต้องสอดคล้องกันในทุกระดับของลำดับชั้น
นอกจากนี้ เนื่องจากกฎไม่มีผลกับเส้นทางหลัก ทั้งการอ่านหรือการเขียน การดำเนินการจะล้มเหลวหากไม่มีกฎในตำแหน่งที่ขอหรือที่ตำแหน่งหลัก สถานที่ที่ให้สิทธิ์เข้าถึง แม้ว่าเส้นทางย่อยทั้งหมดที่ได้รับผลกระทบจะเข้าถึงได้ การอ่านที่ตำแหน่งระดับบนสุดจะล้มเหลวโดยสิ้นเชิง ลองพิจารณาโครงสร้างนี้
{ "rules": { "records": { "rec1": { ".read": true }, "rec2": { ".read": false } } } }
หากคุณไม่เข้าใจว่ากฎจะได้รับการประเมินในเชิงอะตอม ก็อาจดูเหมือน
เช่น การดึงข้อมูลเส้นทาง /records/
จะแสดงผล rec1
แต่ไม่ใช่ rec2
แต่ผลลัพธ์จริงคือข้อผิดพลาด
JavaScript
var db = firebase.database(); db.ref("records").once("value", function(snap) { // success method is not called }, function(err) { // error callback triggered with PERMISSION_DENIED });
Objective-C
FIRDatabaseReference *ref = [[FIRDatabase database] reference]; [[_ref child:@"records"] observeSingleEventOfType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot *snapshot) { // success block is not called } withCancelBlock:^(NSError * _Nonnull error) { // cancel block triggered with PERMISSION_DENIED }];
Swift
var ref = FIRDatabase.database().reference() ref.child("records").observeSingleEventOfType(.Value, withBlock: { snapshot in // success block is not called }, withCancelBlock: { error in // cancel block triggered with PERMISSION_DENIED })
Java
FirebaseDatabase database = FirebaseDatabase.getInstance(); DatabaseReference ref = database.getReference("records"); ref.addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(DataSnapshot snapshot) { // success method is not called } @Override public void onCancelled(FirebaseError firebaseError) { // error callback triggered with PERMISSION_DENIED }); });
REST
curl https://docs-examples.firebaseio.com/rest/records/ # response returns a PERMISSION_DENIED error
เนื่องจากการดำเนินการอ่านที่ /records/
เป็นแบบอะตอม และไม่มีกฎการอ่านที่ให้สิทธิ์เข้าถึงข้อมูลทั้งหมดภายใต้ /records/
การดำเนินการนี้จะแสดงข้อผิดพลาด PERMISSION_DENIED
หากเราประเมินกฎนี้ในเครื่องจำลองความปลอดภัยในคอนโซล Firebase จะพบว่าการดำเนินการอ่านถูกปฏิเสธ
Attempt to read /records with auth=Success(null) / /records No .read rule allowed the operation. Read was denied.
การดำเนินการนี้ถูกปฏิเสธเนื่องจากไม่มีกฎการอ่านที่อนุญาตให้เข้าถึงเส้นทาง /records/
แต่โปรดทราบว่ากฎสำหรับ rec1
ไม่ได้รับการประเมินเนื่องจากไม่ได้อยู่ในเส้นทางที่เราร้องขอ หากต้องการดึงข้อมูล rec1
เราจะต้องเข้าถึงโดยตรง
JavaScript
var db = firebase.database(); db.ref("records/rec1").once("value", function(snap) { // SUCCESS! }, function(err) { // error callback is not called });
Objective-C
FIRDatabaseReference *ref = [[FIRDatabase database] reference]; [[ref child:@"records/rec1"] observeSingleEventOfType:FEventTypeValue withBlock:^(FIRDataSnapshot *snapshot) { // SUCCESS! }];
Swift
var ref = FIRDatabase.database().reference() ref.child("records/rec1").observeSingleEventOfType(.Value, withBlock: { snapshot in // SUCCESS! })
Java
FirebaseDatabase database = FirebaseDatabase.getInstance(); DatabaseReference ref = database.getReference("records/rec1"); ref.addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(DataSnapshot snapshot) { // SUCCESS! } @Override public void onCancelled(FirebaseError firebaseError) { // error callback is not called } });
REST
curl https://docs-examples.firebaseio.com/rest/records/rec1 # SUCCESS!
ตัวแปรสถานที่ตั้ง
Realtime Database Rules รองรับ $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 }
}
}
}