คู่มือนี้สร้างขึ้นจากเรียนรู้ไวยากรณ์หลักของคู่มือภาษาFirebase Security Rules เพื่อแสดงวิธีเพิ่มเงื่อนไขลงใน Firebase Security Rules สำหรับ Cloud Storage
องค์ประกอบที่ใช้สร้างสรรค์หลักของ Cloud Storage Security Rules คือเงื่อนไข ต
คือนิพจน์บูลีนที่กำหนดว่าการดำเนินการหนึ่งๆ หรือไม่
ควรยอมรับหรือปฏิเสธ สำหรับกฎพื้นฐาน ให้ใช้ true
และ false
ลิเทอรัล
เนื่องจากสภาวะต่างๆ ทำงานได้ดี แต่ Firebase Security Rules สำหรับ 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; }
ส่วนตัวของผู้ใช้
โดยทั่วไปกรณีการใช้งาน 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 |
แมป<สตริง, สตริง> | คู่คีย์/ค่าของข้อมูลเมตาที่กำหนดเองเพิ่มเติมที่นักพัฒนาซอฟต์แวร์ระบุ |
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()
คุณต้อง Escape อย่างชัดเจน
โดยใช้ไวยากรณ์ $(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 ใช้งานได้