รักษาความปลอดภัยของข้อมูลผู้ใช้

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;
}

กลุ่มส่วนตัว

อีกกรณีการใช้งานหนึ่งที่พบได้บ่อยคือ อนุญาตสิทธิ์ของกลุ่มในออบเจ็กต์ เช่น อนุญาตให้สมาชิกทีมหลายคนทำงานร่วมกันในเอกสารที่แชร์ มี มีหลายวิธีในการดำเนินการนี้:

เมื่อเก็บข้อมูลนี้ไว้ในโทเค็นหรือข้อมูลเมตาของไฟล์แล้ว ก็จะนำไปอ้างอิงได้ จากภายในกฎ:

// 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;
      }
    }
  }
}