คู่มือนี้สร้างขึ้นจากเรียนรู้ไวยากรณ์หลักของคู่มือภาษาFirebase Security Rules เพื่อแสดงวิธีเพิ่มเงื่อนไขลงใน Firebase Security Rules สำหรับ Cloud Storage
องค์ประกอบที่ใช้สร้างสรรค์หลักของ Cloud Storage Security Rules คือเงื่อนไข ต
คือนิพจน์บูลีนที่กำหนดว่าการดำเนินการหนึ่งๆ หรือไม่
ควรยอมรับหรือปฏิเสธ สำหรับกฎพื้นฐาน ให้ใช้ true
และ false
ลิเทอรัล
เนื่องจากสภาวะต่างๆ ทำงานได้ดี แต่รูปแบบ Firebase Security Rules for Cloud Storage
ช่วยให้คุณเขียนเงื่อนไขที่ซับซ้อนมากขึ้นได้ ซึ่งสามารถทําสิ่งต่อไปนี้
- ตรวจสอบการตรวจสอบสิทธิ์ของผู้ใช้
- ตรวจสอบข้อมูลขาเข้า
การตรวจสอบสิทธิ์
Firebase Security Rules สําหรับ Cloud Storage ผสานรวมกับ Firebase Authentication เพื่อให้ การตรวจสอบสิทธิ์ตามผู้ใช้ที่มีประสิทธิภาพไปยัง Cloud Storage ซึ่งช่วยให้ การควบคุมการเข้าถึงแบบละเอียดตามการอ้างสิทธิ์โทเค็น Firebase Authentication
เมื่อผู้ใช้ที่ตรวจสอบสิทธิ์แล้วส่งคำขอไปยัง Cloud Storage ระบบจะป้อนข้อมูลตัวแปร request.auth
ด้วย uid
(request.auth.uid
) ของผู้ใช้ รวมถึงการอ้างสิทธิ์ของ Firebase Authentication JWT (request.auth.token
)
นอกจากนี้ เมื่อใช้การตรวจสอบสิทธิ์ที่กำหนดเอง การอ้างสิทธิ์เพิ่มเติมจะปรากฏขึ้น
ในช่อง request.auth.token
เมื่อผู้ใช้ที่ไม่ได้รับการตรวจสอบสิทธิ์ส่งคำขอ ตัวแปร request.auth
จะเป็น
null
การใช้ข้อมูลนี้ทำให้มีวิธีทั่วไปหลายวิธีในการใช้การตรวจสอบสิทธิ์เพื่อรักษาความปลอดภัย ไฟล์:
- สาธารณะ: ละเว้น
request.auth
- ตรวจสอบสิทธิ์แบบส่วนตัวแล้ว: ตรวจสอบว่า
request.auth
ไม่ใช่null
- ส่วนตัวของผู้ใช้: ตรวจสอบว่า
request.auth.uid
เท่ากับเส้นทางuid
- ส่วนตัวของกลุ่ม: ตรวจสอบการอ้างสิทธิ์ของโทเค็นที่กำหนดเองเพื่อจับคู่กับการอ้างสิทธิ์ที่เลือก หรืออ่านข้อมูลเมตาของไฟล์เพื่อดูว่ามีช่องข้อมูลเมตาหรือไม่
สาธารณะ
กฎใดก็ตามที่ไม่พิจารณาบริบท request.auth
อาจถือเป็น
public
เนื่องจากไม่พิจารณาบริบทการตรวจสอบสิทธิ์ของผู้ใช้
กฎเหล่านี้อาจเป็นประโยชน์ในการแสดงข้อมูลสาธารณะ เช่น เนื้อหาเกม เสียง
หรือเนื้อหาแบบคงที่อื่นๆ
// Anyone to read a public image if the file is less than 100kB // Anyone can upload a public file ending in '.txt' match /public/{imageId} { allow read: if resource.size < 100 * 1024; allow write: if imageId.matches(".*\\.txt"); }
ความเป็นส่วนตัวที่ตรวจสอบสิทธิ์แล้ว
ในบางกรณี คุณอาจต้องการให้ผู้ใช้ที่ได้รับการตรวจสอบสิทธิ์ทั้งหมดของ
แอปพลิเคชันของคุณ แต่ไม่ใช่โดยผู้ใช้ที่ไม่ได้รับการตรวจสอบสิทธิ์ นับตั้งแต่วันที่ request.auth
คือ null
สำหรับผู้ใช้ที่ไม่ได้รับการตรวจสอบสิทธิ์ทั้งหมด คุณเพียงแค่ทำเครื่องหมาย
มีตัวแปร request.auth
อยู่เพื่อให้ต้องมีการตรวจสอบสิทธิ์
// Require authentication on all internal image reads match /internal/{imageId} { allow read: if request.auth != null; }
ส่วนตัวของผู้ใช้
Use Case ที่พบบ่อยที่สุดสำหรับ request.auth
คือการมอบสิทธิ์แบบละเอียดในไฟล์ให้แก่ผู้ใช้แต่ละราย ตั้งแต่การอัปโหลดรูปโปรไฟล์ไปจนถึงการอ่านเอกสารส่วนตัว
เนื่องจากไฟล์ใน Cloud Storage มี "เส้นทาง" ไปยังไฟล์อย่างสมบูรณ์ สิ่งที่ต้องทำเพื่อให้ผู้ใช้ควบคุมไฟล์ได้คือข้อมูลระบุผู้ใช้ที่ไม่ซ้ำกันในส่วนนำหน้าชื่อไฟล์ (เช่น uid
ของผู้ใช้) ซึ่งสามารถตรวจสอบได้เมื่อระบบประเมินกฎ
// Only a user can upload their profile picture, but anyone can view it match /users/{userId}/profilePicture.png { allow read; allow write: if request.auth.uid == userId; }
กลุ่มส่วนตัว
อีกกรณีการใช้งานหนึ่งที่พบได้บ่อยคือ อนุญาตสิทธิ์ของกลุ่มในออบเจ็กต์ เช่น อนุญาตให้สมาชิกทีมหลายคนทำงานร่วมกันในเอกสารที่แชร์ มี มีหลายวิธีในการดำเนินการนี้:
- สร้างโทเค็นที่กำหนดเอง Firebase Authentication ที่มีข้อมูลเพิ่มเติมเกี่ยวกับสมาชิกกลุ่ม (เช่น รหัสกลุ่ม)
- ใส่ข้อมูลกลุ่ม (เช่น รหัสกลุ่มหรือรายการ
uid
ที่ได้รับอนุญาต) ไว้ใน ข้อมูลเมตาของไฟล์
เมื่อเก็บข้อมูลนี้ไว้ในโทเค็นหรือข้อมูลเมตาของไฟล์แล้ว ก็จะนำไปอ้างอิงได้ จากภายในกฎ:
// Allow reads if the group ID in your token matches the file metadata's `owner` property // Allow writes if the group ID is in the user's custom token match /files/{groupId}/{fileName} { allow read: if resource.metadata.owner == request.auth.token.groupId; allow write: if request.auth.token.groupId == groupId; }
ขอรับการประเมิน
ระบบจะประเมินการอัปโหลด การดาวน์โหลด การเปลี่ยนแปลงข้อมูลเมตา และการลบโดยใช้ request
ที่ส่งไปยัง Cloud Storage นอกเหนือจากรหัสที่ไม่ซ้ำกันของผู้ใช้และ
เพย์โหลด Firebase Authentication ในออบเจ็กต์ request.auth
ตามที่อธิบายไว้ข้างต้น
ตัวแปร request
ประกอบด้วยเส้นทางไฟล์ที่คำขอ
ดำเนินการ เวลาที่ได้รับคำขอ และค่า resource
ใหม่
หากคำขอนั้นเป็นการเขียน
ออบเจ็กต์ 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 |
map<string, string> | คู่คีย์/ค่าของข้อมูลเมตาที่กำหนดเองเพิ่มเติมที่นักพัฒนาซอฟต์แวร์ระบุ |
request.resource
มีองค์ประกอบเหล่านี้ทั้งหมด ยกเว้น generation
,
metageneration
, etag
, timeCreated
และ updated
ปรับปรุงด้วย Cloud Firestore
คุณเข้าถึงเอกสารใน Cloud Firestore เพื่อประเมินการให้สิทธิ์อื่นๆ ได้ เกณฑ์
การใช้ฟังก์ชัน firestore.get()
และ firestore.exists()
ทำให้การรักษาความปลอดภัย
กฎสามารถประเมินคำขอที่เข้ามาโดยเปรียบเทียบกับเอกสารใน Cloud Firestore
ทั้งฟังก์ชัน firestore.get()
และ firestore.exists()
ต้องการอย่างสมบูรณ์
เส้นทางเอกสารที่ระบุ เมื่อใช้ตัวแปรเพื่อสร้างเส้นทางสําหรับ firestore.get()
และ firestore.exists()
คุณต้องหลีกตัวแปรอย่างชัดเจนโดยใช้ไวยากรณ์ $(variable)
ในตัวอย่างด้านล่าง เราจะเห็นกฎที่จำกัดการเข้าถึงในการอ่านไฟล์สำหรับ ผู้ใช้ที่เป็นสมาชิกของสโมสรที่เฉพาะเจาะจง
service firebase.storage { match /b/{bucket}/o { match /users/{club}/files/{fileId} { allow read: if club in firestore.get(/databases/(default)/documents/users/$(request.auth.id)).memberships } } }
service firebase.storage { match /b/{bucket}/o { match /users/{userId}/photos/{fileId} { allow read: if firestore.exists(/databases/(default)/documents/users/$(userId)/friends/$(request.auth.id)) } } }
เมื่อคุณสร้างและบันทึก Cloud Storage Security Rules รายการแรกที่ใช้ Cloud Firestore เหล่านี้ คุณจะได้รับข้อความแจ้งในคอนโซล Firebase หรือ Firebase CLI ให้ เปิดใช้สิทธิ์เพื่อเชื่อมต่อผลิตภัณฑ์ทั้งสอง
คุณสามารถปิดใช้ฟีเจอร์นี้ได้โดยการนำบทบาท IAM ออก ดังที่อธิบายไว้ใน จัดการและทำให้ Firebase Security Rules ใช้งานได้
ตรวจสอบข้อมูล
Firebase Security Rules สําหรับ Cloud Storage ยังใช้สําหรับการตรวจสอบข้อมูลได้อีกด้วย ซึ่งได้แก่
การตรวจสอบชื่อและเส้นทางของไฟล์ รวมถึงคุณสมบัติข้อมูลเมตาของไฟล์
contentType
และ size
service firebase.storage { match /b/{bucket}/o { match /images/{imageId} { // Only allow uploads of any image file that's less than 5MB allow write: if request.resource.size < 5 * 1024 * 1024 && request.resource.contentType.matches('image/.*'); } } }
ฟังก์ชันที่กำหนดเอง
เมื่อ Firebase Security Rules ซับซ้อนมากขึ้น คุณอาจต้องรวมชุดของ ในฟังก์ชันที่คุณนำมาใช้ซ้ำในชุดกฎได้ กฎความปลอดภัย รองรับฟังก์ชันที่กำหนดเอง ไวยากรณ์ของฟังก์ชันที่กําหนดเองจะคล้ายกับ JavaScript เล็กน้อย แต่ฟังก์ชัน Firebase Security Rules เขียนด้วยภาษาเฉพาะโดเมนซึ่งมีข้อจํากัดที่สําคัญบางอย่าง ดังนี้
- ฟังก์ชันจะมีคำสั่ง
return
ได้เพียงคำสั่งเดียว จึงไม่สามารถ มีตรรกะเพิ่มเติม เช่น ไม่สามารถเรียกใช้ลูปหรือเรียกบริการภายนอก - ฟังก์ชันจะเข้าถึงฟังก์ชันและตัวแปรจากขอบเขตได้โดยอัตโนมัติ
ตามที่มีการกำหนดไว้ ตัวอย่างเช่น ฟังก์ชันที่กำหนดภายใน
ขอบเขต
service firebase.storage
มีสิทธิ์เข้าถึง ตัวแปรresource
และฟังก์ชันในตัวสำหรับ Cloud Firestore เท่านั้น เช่นget()
และexists()
- ฟังก์ชันต่างๆ อาจเรียกใช้ฟังก์ชันอื่นๆ แต่อาจไม่แสดงใหม่ การโทรทั้งหมด จำกัดความลึกของสแต็กไว้ที่ 10
- ในเวอร์ชัน
rules2
ฟังก์ชันจะกำหนดตัวแปรโดยใช้คีย์เวิร์ดlet
ได้ ฟังก์ชันมีการเชื่อมโยง Let ๆ กี่รายการก็ได้ แต่ต้องลงท้ายด้วยการส่งกลับ ข้อความ
ฟังก์ชันจะกำหนดด้วยคีย์เวิร์ด function
และใช้อาร์กิวเมนต์ได้ตั้งแต่ 0 รายการขึ้นไป เช่น คุณอาจต้องการรวมเงื่อนไข 2 ประเภทที่ใช้รวมกัน
ในตัวอย่างข้างต้นให้เป็นฟังก์ชันเดียว
service firebase.storage {
match /b/{bucket}/o {
// 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 /images/{imageId} {
allow read, write: if signedInOrPublic();
}
match /mp3s/{mp3Ids} {
allow read: if signedInOrPublic();
}
}
}
การใช้ฟังก์ชันใน Firebase Security Rules จะช่วยให้ดูแลรักษาได้ง่ายขึ้นเมื่อกฎมีความซับซ้อนมากขึ้น
ขั้นตอนถัดไป
หลังจากปรึกษาหารือเกี่ยวกับเงื่อนไขกันแล้ว คุณมีทางเลือกมากขึ้น เข้าใจกฎเกณฑ์ และพร้อมที่จะ:
ดูวิธีจัดการกรณีการใช้งานหลักและดูเวิร์กโฟลว์สำหรับการพัฒนา การทดสอบ และการใช้กฎ
- เขียนกฎที่กล่าวถึงสถานการณ์ที่พบบ่อย
- เพิ่มพูนความรู้ของคุณโดยดูสถานการณ์ที่คุณต้องตรวจหาและหลีกเลี่ยงกฎที่ไม่ปลอดภัย
- ทดสอบกฎโดยใช้โปรแกรมจำลอง Cloud Storage และไลบรารีการทดสอบกฎการรักษาความปลอดภัยโดยเฉพาะ
- ดูวิธีการสำหรับการทำให้ Rules ใช้งานได้