คู่มือนี้สร้างขึ้นจากการ เรียนรู้ไวยากรณ์หลักของคู่มือภาษากฎความปลอดภัยของ Firebase เพื่อแสดงวิธีเพิ่มเงื่อนไขให้กับกฎความปลอดภัยของ Firebase สำหรับ Cloud Storage
โครงสร้างหลักของกฎความปลอดภัยของ Cloud Storage คือ เงื่อนไข เงื่อนไขคือนิพจน์บูลีนที่กำหนดว่าการดำเนินการเฉพาะควรได้รับอนุญาตหรือปฏิเสธ สำหรับกฎพื้นฐาน การใช้สัญพจน์ true
และ false
เป็นเงื่อนไขที่ใช้ได้ผลดีกับนายอำเภอ แต่ภาษา Firebase Security Rules สำหรับ Cloud Storage ช่วยให้คุณสามารถเขียนเงื่อนไขที่ซับซ้อนมากขึ้นซึ่งสามารถ:
- ตรวจสอบการพิสูจน์ตัวตนผู้ใช้
- ตรวจสอบข้อมูลขาเข้า
การตรวจสอบสิทธิ์
กฎความปลอดภัยของ Firebase สำหรับ Cloud Storage ทำงานร่วมกับ Firebase Authentication เพื่อให้การรับรองความถูกต้องตามผู้ใช้ที่มีประสิทธิภาพไปยัง Cloud Storage ซึ่งช่วยให้สามารถควบคุมการเข้าถึงแบบละเอียดตามการอ้างสิทธิ์ของโทเค็นการตรวจสอบสิทธิ์ Firebase
เมื่อผู้ใช้ที่ตรวจสอบสิทธิ์ดำเนินการตามคำขอกับ 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 ที่มีข้อมูลเพิ่มเติมเกี่ยวกับสมาชิกกลุ่ม (เช่น ID กลุ่ม)
- รวมข้อมูลกลุ่ม (เช่น ID กลุ่มหรือรายการ
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 นอกจาก ID เฉพาะของผู้ใช้และเพย์โหลดการตรวจสอบสิทธิ์ของ Firebase ในออบเจ็กต์ request.auth
ตามที่อธิบายข้างต้นแล้ว ตัวแปร request
ยังมีเส้นทางของไฟล์ที่ดำเนินการตามคำขอ เวลาที่ได้รับคำขอ และค่า resource
ใหม่หาก คำขอคือการเขียน รวมส่วนหัว HTTP และสถานะการตรวจสอบสิทธิ์ด้วย
ออบเจ็กต์ request
ยังมี ID เฉพาะของผู้ใช้และเพย์โหลดการตรวจสอบสิทธิ์ Firebase ในอ็อบเจ็กต์ request.auth
ซึ่งจะอธิบายเพิ่มเติมในส่วน ความปลอดภัยตามผู้ ใช้ของเอกสาร
รายการคุณสมบัติทั้งหมดในวัตถุ request
มีอยู่ด้านล่าง:
คุณสมบัติ | พิมพ์ | คำอธิบาย |
---|---|---|
auth | แผนที่<สตริง สตริง> | เมื่อผู้ใช้เข้าสู่ระบบ ให้ระบุ uid ID เฉพาะของผู้ใช้ และ token แผนที่ของ Firebase Authentication JWT อ้างสิทธิ์ มิฉะนั้นจะเป็น null |
params | แผนที่<สตริง สตริง> | แผนที่ที่มีพารามิเตอร์การค้นหาของคำขอ |
path | เส้นทาง | path ที่แสดงเส้นทางที่ร้องขอกำลังดำเนินการอยู่ |
resource | แผนที่<สตริง สตริง> | ค่าทรัพยากรใหม่ แสดงเฉพาะในคำขอ write |
time | การประทับเวลา | การประทับเวลาที่แสดงเวลาเซิร์ฟเวอร์ที่คำขอได้รับการประเมิน |
การประเมินทรัพยากร
เมื่อประเมินกฎ คุณอาจต้องการประเมินข้อมูลเมตาของไฟล์ที่กำลังอัปโหลด ดาวน์โหลด แก้ไข หรือลบ วิธีนี้ช่วยให้คุณสร้างกฎที่ซับซ้อนและมีประสิทธิภาพซึ่งทำสิ่งต่างๆ เช่น อนุญาตให้อัปโหลดเฉพาะไฟล์ที่มีเนื้อหาบางประเภท หรือลบเฉพาะไฟล์ที่มีขนาดใหญ่กว่าขนาดที่กำหนด
กฎความปลอดภัยของ Firebase สำหรับ Cloud Storage ให้ข้อมูลเมตาของไฟล์ในออบเจ็กต์ resource
ซึ่งประกอบด้วยคู่คีย์/ค่าของข้อมูลเมตาที่แสดงในออบเจ็กต์ Cloud Storage คุณสมบัติเหล่านี้สามารถตรวจสอบได้ในคำขอ read
หรือ write
เพื่อรับรองความถูกต้องของข้อมูล
ในคำขอ write
(เช่น การอัปโหลด การอัปเดตข้อมูลเมตา และการลบ) นอกเหนือจากออบเจ็กต์ resource
ซึ่งมีข้อมูลเมตาของไฟล์สำหรับไฟล์ที่มีอยู่ในปัจจุบันที่เส้นทางคำขอ คุณยังมีความสามารถในการใช้อ็อบเจ็กต์ request.resource
ซึ่งมีชุดย่อยของข้อมูลเมตาของไฟล์ที่จะเขียนหากอนุญาตให้เขียน คุณสามารถใช้สองค่านี้เพื่อรับรองความถูกต้องของข้อมูลหรือบังคับใช้ข้อจำกัดของแอปพลิเคชัน เช่น ประเภทหรือขนาดไฟล์
รายการคุณสมบัติทั้งหมดในวัตถุ resource
มีอยู่ด้านล่าง:
คุณสมบัติ | พิมพ์ | คำอธิบาย |
---|---|---|
name | สตริง | ชื่อเต็มของวัตถุ |
bucket | สตริง | ชื่อของบัคเก็ตที่วัตถุนี้อยู่ |
generation | int | การ สร้างวัตถุ Google Cloud Storage ของวัตถุนี้ |
metageneration | int | การสร้าง เมตาอ็อบเจ็กต์ Google Cloud Storage ของออบเจ็กต์นี้ |
size | int | ขนาดของวัตถุเป็นไบต์ |
timeCreated | การประทับเวลา | การประทับเวลาแสดงเวลาที่วัตถุถูกสร้างขึ้น |
updated | การประทับเวลา | การประทับเวลาแสดงเวลาที่วัตถุได้รับการอัปเดตครั้งล่าสุด |
md5Hash | สตริง | แฮช MD5 ของอ็อบเจ็กต์ |
crc32c | สตริง | แฮช crc32c ของอ็อบเจ็กต์ |
etag | สตริง | etag ที่เกี่ยวข้องกับวัตถุนี้ |
contentDisposition | สตริง | การจัดการเนื้อหาที่เกี่ยวข้องกับวัตถุนี้ |
contentEncoding | สตริง | การเข้ารหัสเนื้อหาที่เกี่ยวข้องกับวัตถุนี้ |
contentLanguage | สตริง | ภาษาของเนื้อหาที่เกี่ยวข้องกับวัตถุนี้ |
contentType | สตริง | ชนิดเนื้อหาที่เกี่ยวข้องกับวัตถุนี้ |
metadata | แผนที่<สตริง สตริง> | คู่คีย์/ค่าของข้อมูลเมตาที่กำหนดเองเพิ่มเติมที่นักพัฒนาระบุ |
request.resource
มีสิ่งเหล่านี้ทั้งหมด ยกเว้น generation
, metageneration
, etag
, timeCreated
และ updated
ตรวจสอบข้อมูล
กฎความปลอดภัยของ Firebase สำหรับ 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 มีความซับซ้อนมากขึ้น คุณอาจต้องการรวมชุดเงื่อนไขไว้ในฟังก์ชันที่นำมาใช้ซ้ำได้ทั่วทั้งชุดกฎ กฎความปลอดภัยรองรับฟังก์ชันที่กำหนดเอง ไวยากรณ์สำหรับฟังก์ชันที่กำหนดเองนั้นคล้ายกับ JavaScript แต่ฟังก์ชัน Firebase Security Rules เขียนด้วยภาษาเฉพาะโดเมนซึ่งมีข้อจำกัดที่สำคัญบางประการ:
- ฟังก์ชันสามารถมีคำสั่ง
return
ได้เพียงคำสั่งเดียว พวกเขาไม่สามารถมีตรรกะเพิ่มเติมใด ๆ ตัวอย่างเช่น ไม่สามารถรันลูปหรือเรียกใช้บริการภายนอกได้ - ฟังก์ชันสามารถเข้าถึงฟังก์ชันและตัวแปรได้โดยอัตโนมัติจากขอบเขตที่กำหนดไว้ ตัวอย่างเช่น ฟังก์ชันที่กำหนดไว้ภายในขอบเขต
service firebase.storage
มีสิทธิ์เข้าถึงตัวแปรresource
และสำหรับ Cloud Firestore เท่านั้น ฟังก์ชันในตัว เช่นget()
และexists()
- ฟังก์ชันอาจเรียกใช้ฟังก์ชันอื่นๆ แต่ไม่สามารถเรียกซ้ำได้ ความลึกของสแต็กการโทรทั้งหมดถูกจำกัดที่ 10
- ในเวอร์ชัน
rules2
ฟังก์ชันสามารถกำหนดตัวแปรได้โดยใช้คีย์เวิร์ดlet
ฟังก์ชันสามารถมีจำนวนการโยงแบบใดก็ได้ แต่ต้องลงท้ายด้วยคำสั่ง return
ฟังก์ชั่นถูกกำหนดด้วยคีย์เวิร์ดของ function
และรับอาร์กิวเมนต์เป็นศูนย์หรือมากกว่า ตัวอย่างเช่น คุณอาจต้องการรวมเงื่อนไขสองประเภทที่ใช้ในตัวอย่างด้านบนเป็นฟังก์ชันเดียว:
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 ทำให้สามารถบำรุงรักษาได้มากขึ้นเมื่อกฎของคุณมีความซับซ้อนมากขึ้น
ขั้นตอนถัดไป
หลังจากการหารือเกี่ยวกับเงื่อนไขนี้ คุณมีความเข้าใจกฎเกณฑ์ที่ซับซ้อนมากขึ้นและพร้อมที่จะ:
เรียนรู้วิธีจัดการกับกรณีการใช้งานหลัก และเรียนรู้เวิร์กโฟลว์สำหรับการพัฒนา ทดสอบ และปรับใช้กฎ:
- เขียนกฎที่กล่าวถึง สถานการณ์ทั่วไป
- สร้างจากความรู้ของคุณโดยทบทวนสถานการณ์ที่คุณต้อง สังเกตและหลีกเลี่ยงกฎที่ไม่ปลอดภัย
- กฎการทดสอบโดยใช้ โปรแกรมจำลอง Cloud Storage และไลบรารีทดสอบกฎความปลอดภัยเฉพาะ
- ตรวจสอบวิธีการที่ใช้ได้สำหรับการ ปรับใช้กฎ