รู้จัก Security Rules ใน Cloud Storage for Firebase

Jirawatee
Firebase Thailand

--

สิ่งหนึ่งที่สำคัญและมีความซับซ้อนในการพัฒนา Software ก็คือเรื่องของ “ความปลอดภัย” บทความนี้จะพูดถึงความปลอดภัยในการเข้าถึงและการตรวจสอบไฟล์ ที่ Cloud Storage for Firebase Security Rules ได้เตรียมมาให้เราสามารถจัดการได้ด้วย code เพียงไม่กี่บรรทัด และไม่ต้องเขียนโค้ดในฝั่ง server-side เลย

การกำหนด Rules

การกำหนด Rules ใน Storage Security Rules จะต้องเริ่มต้นด้วย service (service firebase.storage) ชั้นต่อมาคือ Firebase Storage bucket (match /b/<your-firebase-storage-bucket>/o) และชั้นต่อๆมาก็จะเป็น rules อื่นๆตามแต่ละ path ใน bucket ละครับ

Rule พื้นฐานของ Storage Security Rules จะมี 2 ประเภท

1. allow เป็น rule ที่ใช้กำหนดการเข้าถึงและตรวจสอบไฟล์ทั้ง read และ write โดยเราจะสามารถใช้ if ในการกำหนดเงื่อนไข

allow read; // read ตามที่สบายใจallow write: if <condition>; // เงื่อนไขสำหรับการ write เท่านั้นallow read, write: if <condition>; // read ได้ แต่ write มีเงื่อนไขนะ

2. match เป็น rule ที่ใช้กำหนด path จะมีทั้งแบบตรงกันเป๊ะ, แบบซ้อนกัน และแบบ Wildcard โดยสามารถมีได้หลาย rule ใน 1 path

// เป๊ะ (Exact)
match
/images/profilePhoto.png {
allow write: if <condition>;
}
// ซ้อนกันกี่ชั้นก็ได้ แต่ไม่ควรซ้อน 3 เพราะตำรวจจับ (Nested)
match /images {
match /profilePhoto.png {
allow write: if <condition>;
}

match /croppedProfilePhoto.png {
allow write: if <other_condition>;
}
}
// มีรูปแบบ (Wildcard)
match /images {
// images/profilePhoto.png is matched
match /{imageId} {
// This rule only matches a single path segment (*)
allow read: if <condition>;
}

// images/users/user:12345/profilePhoto.png is matched
// images/profilePhoto.png is also matched
match /{allImages=**} {
// This rule matches one or more path segments (**)
allow read: if <other_condition>;
}
}
// พิเศษแบบ Wildcard สามารถจำกัดชื่อไฟล์ได้ด้วยนะเธอว์
match /images/{imageId} {
allow read: if imageId == "profilePhoto.png";
}

นอกจากนั้นก็ยังมี request ที่จะให้ข้อมูลสำหรับเงื่อนไขต่างๆ เช่น request.auth ที่สามารถเช็คสิทธิ์ในการเข้าถึง หรือจะเป็น request.resource.size ที่สามารถเช็คขนาดไฟล์ คลิกเพื่อดูรายการของ request และ resource ทั้งหมด

match /images/profilePhoto.png {
allow write: if request.auth != null
&& request.resource.size < 5 * 1024 * 1024;
}

การจำกัดการเข้าถึง

การจำกัดการเข้าถึงไฟล์ของ Cloud Storage for Firebase นั้นจะใช้ Firebase Authentication มาเป็นตัวกำหนดสิทธิ์ ซึ่งเมื่อผู้ใช้ได้ผ่านการ authen มาแล้ว ตัวแปร request.auth ใน Storage Security Rules จะสามารถดึงค่า UID(request.auth.uid) และข้อมูลผู้ใช้ทั้งหมดผ่าน Token(request.auth.token) ของผู้ใช้ได้ แต่หากไม่ผ่านการ authen มา ตัวแปร request.auth จะมีค่าเป็น null

คุณสามารถกำหนดการเข้าถึงใน แต่ละไฟล์, แต่ละ path หรือทั้งหมด ได้ทั้งแบบ read และ write ผ่าน Firebase Console โดยเลือกเข้าไปที่เมนู Storage และเลือก tab RULES ตามภาพ

ค่าเริ่มต้นของ Storage Security Rules

ตัวอย่างการจำกัดการเข้าถึงแบบต่างๆ
1. DEFAULT แบบที่จะต้อง authen ก่อนจึงจะ write ได้

service firebase.storage {
match /b/<your-firebase-storage-bucket>/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}

2. PUBLIC แบบที่สามารถ read และ write ได้โดยใครก็ได้ (ไม่ต้อง authen)

service firebase.storage {
match /b/<your-firebase-storage-bucket>/o {
match /{allPaths=**} {
allow read, write;
}
// หรือ
// ใครอ่านก็ได้ถ้าไฟล์เล็กกว่า 100KB
// ใคร upload ก็ได้แต่ไฟล์ต้องมีนามสกุล .txt
match /public/{imageId} {
allow read: if resource.size < 100 * 1024;
allow write: if imageId.matches(".*\.txt");
}
}
}

3. USER แบบที่สามารถเจาะจงผู้ใช้ให้สามารถ write ไฟล์ใน path ของผู้ใช้เอง

service firebase.storage {
match /b/<your-firebase-storage-bucket>/o {
// ตัวอย่าง "user/<UID>/path/to/file.txt"
match /user/{userId}/{allPaths=**} {
allow read;
allow write: if request.auth.uid == userId;
}
}
}

4. PRIVATE แบบที่สามารถ read ได้เท่านั้น

service firebase.storage {
match /b/<your-firebase-storage-bucket>/o {
match /{allPaths=**} {
allow read, write: if false;
}
}
}

การตรวจสอบไฟล์

Cloud Storage for Firebase Security Rules สามารถตรวจสอบไฟล์ได้ ไม่ว่าจะเป็น ชื่อไฟล์, path ของไฟล์ หรือแม้กระทั่ง metadata ของไฟล์ได้
ตัวอย่าง ที่ path /images จะอนุญาตให้อัพโหลดเฉพาะรูปภาพ ที่มีขนาดเล็กกว่า 5MB

service firebase.storage {
match /b/<your-firebase-storage-bucket>/o {
match /images/{imageId} {
allow write: if request.resource.size < 5 * 1024 * 1024
&& request.resource.contentType.matches('image/.*');
}
}
}

ตัวอย่างมาเต็ม

service firebase.storage {
match /b/<your-firebase-storage-bucket>/o {
match /images {
// Cascade read to any image type at any path
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 user/ images
match /user/{userId}/{imageId} {
allow write: if request.auth.uid == userId;
}
// Allow write files to the path "images/*"
// 1) File size is less than 5MB
// 2) Content type is an image
// 3) Uploaded content type matches existing content type
// 4) File name is less than 32 characters
match /{imageId} {
allow write: if request.resource.size < 5 * 1024 * 1024
&& request.resource.contentType.matches('image/.*')
&& request.resource.contentType == resource.contentType
&& imageId.size() < 32
}
}
}
}

เก็บตกมาแล้วจ้า

การ Publish security rules แต่ละครั้งอาจใช้เวลา 1–5 นาที จึงจะอัพเดทให้เป็นผล

บทความเรื่อง Cloud Storage for Firebase Security Rules นี้ก็สามารถเอาไปประยุกต์ใช้ได้ทั้งกับ Android, iOS และ Web ซึ่งไม่ยากเลยช่ายมะที่จะควบคุม Storage ของคุณให้มีความปลอดภัย ส่วนบทความเรื่อง Firebase Realtime Database Secuiry Rules จะตามมาอีกแน่นอน โปรดติดตามตอนต่อไป สำหรับวันนี้ขอลาไปก่อน ราตรีสวัสดิ์ พี่น้องชาวไทย

--

--

Jirawatee
Firebase Thailand

Technology Evangelist at LINE Thailand / Google Developer Expert in Firebase