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; }
ส่วนตัวของผู้ใช้
โดยทั่วไปกรณีการใช้งาน 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 != null && 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; }
ตัวอย่างแบบเต็ม
ระบบจะแสดงกรณีง่ายๆ ของข้อจำกัดการตรวจสอบสิทธิ์ 4 ประเภทที่พบบ่อย ในตัวอย่างด้านล่าง
service firebase.storage { match /b/{bucket}/o { match /images { // Anyone can view any image (no auth, publicly readable) match /{allImages=**} { allow read; } // Only authenticated users can write to "public" images match /public/{imageId} { allow write: if request.auth != null; } // Only an individual user can write to "their" images match /{userId}/{imageId} { allow write: if request.auth.uid == userId; } // Allow a "group" of users to read/write to shared images // An owner metadata property on the object contains the groupId for reads // A custom token has been minted with a groupId property for writes match /{groupId}/{imageId} { allow read: if resource.metadata.owner == request.auth.token.groupId; allow write: if request.auth.token.groupId == groupId; } } } }