คู่มือนี้ต่อยอดจากคู่มือเรียนรู้ไวยากรณ์หลักของภาษา Firebase Security Rules เพื่อแสดงวิธีเพิ่มเงื่อนไขลงใน Firebase Security Rules สำหรับ Cloud Storage
องค์ประกอบพื้นฐานหลักของ Cloud Storage Security Rules คือเงื่อนไข
เงื่อนไขคือนิพจน์บูลีนที่กำหนดว่าควรอนุญาตหรือปฏิเสธการดำเนินการหนึ่งๆ
สำหรับกฎพื้นฐาน การใช้ตัวอักษร true และ false เป็นเงื่อนไขจะทำงานได้อย่างสมบูรณ์ แต่Firebase Security RulesสำหรับCloud Storage
ภาษาช่วยให้คุณเขียนเงื่อนไขที่ซับซ้อนมากขึ้นได้ ซึ่งจะทำสิ่งต่อไปนี้ได้
- ตรวจสอบการตรวจสอบสิทธิ์ผู้ใช้
- ตรวจสอบข้อมูลขาเข้า
พรอมต์ AI สำหรับความช่วยเหลือจาก AI
หากต้องการความช่วยเหลือจาก AI ให้คัดลอกพรอมต์ด้านล่างลงใน เอเจนต์การเขียนโค้ด AI (เช่น Gemini ใน Android Studio, Antigravity, Claude Code, Codex และ Cursor) คุณปรับแต่งพรอมต์และทำซ้ำกับเอเจนต์ได้ ดูข้อมูลการติดตั้งโดยละเอียดได้ที่ ทักษะเอเจนต์ Firebase
Help me use Firebase in my app.
1. Make sure that **Firebase agent skills** are installed and updated. For Claude Code, Codex, or Cursor agents, help me install the Firebase plugin. For other agents, run `npx skills add firebase/agent-skills`. Always try to use **Firebase agent skills** for Firebase-related tasks.
2. Help me write, validate, and deploy Firebase Security Rules to protect my app's Cloud Storage data.
การตรวจสอบสิทธิ์
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 |
map<string, string> | เมื่อผู้ใช้เข้าสู่ระบบ ระบบจะระบุ uid, รหัสที่ไม่ซ้ำของผู้ใช้ และ
token ซึ่งเป็นแผนที่ของอ้างสิทธิ์ JWT ของ Firebase Authentication ไม่เช่นนั้นจะเป็น
null |
params |
map<string, string> | แผนที่ที่มีพารามิเตอร์การค้นหาของคำขอ |
path |
เส้นทาง | path ที่แสดงเส้นทางที่คำขออยู่ระหว่างการ
ดำเนินการ |
resource |
map<string, string> | ค่าทรัพยากรใหม่ซึ่งแสดงในคำขอ write เท่านั้น
|
time |
การประทับเวลา | การประทับเวลาที่แสดงเวลาเซิร์ฟเวอร์ที่ประเมินคำขอ |
การประเมินทรัพยากร
เมื่อประเมินกฎ คุณอาจต้องประเมินข้อมูลเมตาของไฟล์ที่กำลังอัปโหลด ดาวน์โหลด แก้ไข หรือลบด้วย ซึ่งจะช่วยให้คุณสร้างกฎที่ซับซ้อนและมีประสิทธิภาพซึ่งทำสิ่งต่างๆ ได้ เช่น อนุญาตให้อัปโหลดเฉพาะไฟล์ที่มีประเภทเนื้อหาที่เฉพาะเจาะจง หรืออนุญาตให้ลบเฉพาะไฟล์ที่มีขนาดใหญ่กว่าขนาดที่เฉพาะเจาะจง
Firebase Security Rules สำหรับ Cloud Storage จะให้ข้อมูลเมตาของไฟล์ในออบเจ็กต์ resource
ซึ่งมีคู่คีย์/ค่าของข้อมูลเมตาที่แสดงในออบเจ็กต์ Cloud Storage
คุณตรวจสอบพร็อพเพอร์ตี้เหล่านี้ได้ในคำขอ read หรือ write เพื่อให้มั่นใจว่าข้อมูลมีความสมบูรณ์
ในwrite คำขอ (เช่น การอัปโหลด การอัปเดตข้อมูลเมตา และการลบ) นอกเหนือจากออบเจ็กต์ resource ซึ่งมีข้อมูลเมตาของไฟล์สำหรับไฟล์ที่อยู่ในเส้นทางคำขอในปัจจุบัน คุณยังใช้request.resource ออบเจ็กต์ได้ด้วย ซึ่งมีชุดย่อยของข้อมูลเมตาของไฟล์ที่จะเขียนหากได้รับอนุญาตให้เขียน คุณใช้ค่าทั้ง 2 นี้เพื่อให้มั่นใจในความสมบูรณ์ของข้อมูล
หรือบังคับใช้ข้อจํากัดของแอปพลิเคชัน เช่น ประเภทหรือขนาดไฟล์
รายการพร็อพเพอร์ตี้ทั้งหมดในออบเจ็กต์ resource มีดังนี้
| พร็อพเพอร์ตี้ | ประเภท | คำอธิบาย |
|---|---|---|
name |
สตริง | ชื่อเต็มของออบเจ็กต์ |
bucket |
สตริง | ชื่อของ Bucket ที่ออบเจ็กต์นี้อยู่ |
generation |
int | Google Cloud Storage การสร้างออบเจ็กต์ของออบเจ็กต์นี้ |
metageneration |
int | Google Cloud Storage metageneration ของออบเจ็กต์นี้ |
size |
int | ขนาดของออบเจ็กต์ในหน่วยไบต์ |
timeCreated |
การประทับเวลา | การประทับเวลาที่แสดงเวลาที่สร้างออบเจ็กต์ |
updated |
การประทับเวลา | การประทับเวลาที่แสดงเวลาที่มีการอัปเดตออบเจ็กต์ครั้งล่าสุด |
md5Hash |
สตริง | แฮช MD5 ของออบเจ็กต์ |
crc32c |
สตริง | แฮช crc32c ของออบเจ็กต์ |
etag |
สตริง | แท็ก E ที่เชื่อมโยงกับออบเจ็กต์นี้ |
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() ทั้ง 2 ฟังก์ชันต้องมีเส้นทางเอกสารที่ระบุอย่างครบถ้วน
เมื่อใช้ตัวแปรเพื่อสร้างเส้นทางสำหรับ
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)).data.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 หรือ CLI ของ Firebase ให้ เปิดใช้สิทธิ์เพื่อเชื่อมต่อผลิตภัณฑ์ทั้ง 2 รายการ
คุณปิดใช้ฟีเจอร์นี้ได้โดยนำบทบาท 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 เท่าใดก็ได้ แต่ต้องลงท้ายด้วยคำสั่ง return
ฟังก์ชันจะกำหนดด้วยคีย์เวิร์ด 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โปรแกรมจำลองและคลังทดสอบกฎความปลอดภัยเฉพาะ
- ดูวิธีการที่ใช้ได้สำหรับการติดตั้งใช้งาน Security Rules