กฎความปลอดภัยพื้นฐาน

Firebase Security Rules ให้คุณควบคุมการเข้าถึงข้อมูลที่จัดเก็บไว้ กฎที่ยืดหยุ่น ไวยากรณ์หมายความว่า คุณสามารถสร้างกฎที่ตรงกับอะไรก็ได้ ตั้งแต่การเขียนทั้งหมดไปจนถึง ฐานข้อมูลทั้งหมดไปยังการดำเนินงานในเอกสารที่ระบุ

คู่มือนี้จะอธิบายกรณีการใช้งานพื้นฐานบางอย่างที่คุณอาจต้องการ ขณะที่คุณตั้งค่าแอปและปกป้องข้อมูล แต่ก่อนที่คุณจะ คุณสามารถเริ่มเขียนกฎเกณฑ์ สำหรับข้อมูลเพิ่มเติม ภาษาที่ผู้ใช้เขียนและพฤติกรรมของผู้ใช้

หากต้องการเข้าถึงและอัปเดตกฎ ให้ทำตามขั้นตอนที่ระบุไว้ใน จัดการและทำให้ Firebase Security Rules ใช้งานได้

กฎเริ่มต้น: โหมดล็อกขณะคุมสอบ

เมื่อคุณสร้างฐานข้อมูลหรืออินสแตนซ์พื้นที่เก็บข้อมูลในคอนโซล Firebase คุณเลือกได้ว่าจะFirebase Security Rulesจำกัดการเข้าถึงข้อมูลหรือไม่ (โหมดล็อกขณะคุมสอบ) หรืออนุญาตให้ทุกคนเข้าถึง (โหมดทดสอบ) ใน Cloud Firestore และ Realtime Database ซึ่งเป็นกฎเริ่มต้นสำหรับโหมดล็อกขณะคุมสอบจะปฏิเสธไม่ให้ผู้ใช้ทุกคนเข้าถึง ใน Cloud Storage มีเพียงผู้ใช้ที่ผ่านการตรวจสอบสิทธิ์เท่านั้นที่เข้าถึงที่เก็บข้อมูลของพื้นที่เก็บข้อมูลได้

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if false;
    }
  }
}

Realtime Database

{
  "rules": {
    ".read": false,
    ".write": false
  }
}

Cloud Storage

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

กฎสภาพแวดล้อมการพัฒนา

ระหว่างที่สร้างแอป คุณอาจต้องการที่ค่อนข้างเปิดกว้างหรือไม่มีอิสระในอิสระ เข้าถึงข้อมูลของคุณ เพียงอย่าลืมอัปเดต Rules ก่อนวันที่ คุณทำให้แอปใช้งานได้ในเวอร์ชันที่ใช้งานจริง นอกจากนี้ โปรดทราบว่าหากทําให้แอปใช้งานได้ ผู้ใช้จะเข้าถึงแอปได้แบบสาธารณะ แม้ว่าคุณจะยังไม่ได้เปิดตัวแอปก็ตาม

โปรดทราบว่า Firebase อนุญาตให้ไคลเอ็นต์เข้าถึงข้อมูลของคุณโดยตรง และ Firebase Security Rules เป็นมาตรการป้องกันเพียงอย่างเดียวที่บล็อกการเข้าถึงของผู้ใช้ที่เป็นอันตราย การให้คำจำกัดความ กฎที่แยกจากตรรกะผลิตภัณฑ์มีข้อดีหลายประการ คือ มีหน้าที่บังคับใช้การรักษาความปลอดภัย การติดตั้งใช้งานที่มีข้อบกพร่องจะไม่ได้รับผลกระทบ ข้อมูลของคุณ และที่สำคัญที่สุดคือ คุณไม่ต้องพึ่งพาเซิร์ฟเวอร์ตัวกลาง เพื่อปกป้องข้อมูลจากทั่วโลก

ผู้ใช้ที่ได้รับการตรวจสอบสิทธิ์ทั้งหมด

แม้เราจะไม่แนะนําให้ปล่อยให้ผู้ใช้ทุกคนเข้าถึงข้อมูลได้ เมื่อลงชื่อเข้าใช้แล้ว การตั้งค่าสิทธิ์การเข้าถึงแก่ผู้ใช้ที่ตรวจสอบสิทธิ์แล้วอาจมีประโยชน์ ที่คุณพัฒนาแอป

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth != null;
    }
  }
}

Realtime Database

{
  "rules": {
    ".read": "auth.uid !== null",
    ".write": "auth.uid !== null"
  }
}

Cloud Storage

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

กฎที่พร้อมใช้งานจริง

ระหว่างที่คุณเตรียมทำให้แอปใช้งานได้ โปรดตรวจสอบว่าข้อมูลได้รับการปกป้อง และ ว่ามีการให้สิทธิ์เข้าถึงแก่ผู้ใช้อย่างเหมาะสม ใช้ประโยชน์จาก Authentication เพื่อตั้งค่าการเข้าถึงตามผู้ใช้และการอ่านโดยตรง จากฐานข้อมูลของคุณเพื่อตั้งค่าการเข้าถึงตามข้อมูล

พิจารณาการเขียนกฎเมื่อคุณจัดโครงสร้างข้อมูล เพราะวิธีการ การตั้งค่ากฎจะมีผลต่อวิธีที่คุณจำกัดการเข้าถึงข้อมูล เส้นทาง

สิทธิ์เข้าถึงสำหรับเจ้าของเนื้อหาเท่านั้น

กฎเหล่านี้จำกัดการเข้าถึงไว้สำหรับเจ้าของเนื้อหาที่ตรวจสอบสิทธิ์แล้วเท่านั้น ข้อมูลดังกล่าวจะมีเพียงผู้ใช้รายเดียวที่อ่านและเขียนได้ และเส้นทางข้อมูลจะมีรหัสของผู้ใช้

เมื่อกฎนี้ทำงาน: กฎนี้จะทํางานได้ดีหากผู้ใช้แยกข้อมูลตามระบบ ในกรณีที่ ผู้ใช้เพียงรายเดียวที่ต้องการเข้าถึงข้อมูล คือผู้ใช้รายเดียวกัน

เมื่อกฎนี้ไม่ทำงาน: ชุดกฎนี้จะไม่ทำงานเมื่อมีผู้ใช้หลายคน ต้องเขียนหรืออ่านข้อมูลเดียวกัน ผู้ใช้จะเขียนทับข้อมูลไม่ได้ ในการเข้าถึงข้อมูลที่สร้างขึ้น

วิธีตั้งค่ากฎนี้: สร้างกฎที่ยืนยันผู้ใช้ที่ขอสิทธิ์เข้าถึง ที่จะอ่านหรือเขียนข้อมูลคือผู้ใช้ที่เป็นเจ้าของข้อมูลนั้น

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow only authenticated content owners access
    match /some_collection/{userId}/{documents=**} {
      allow read, write: if request.auth != null && request.auth.uid == userId
    }
  }
}

Realtime Database

{
  "rules": {
    "some_path": {
      "$uid": {
        // Allow only authenticated content owners access to their data
        ".read": "auth !== null && auth.uid === $uid",
        ".write": "auth !== null && auth.uid === $uid"
      }
    }
  }
}

Cloud Storage

// Grants a user access to a node matching their user ID
service firebase.storage {
  match /b/{bucket}/o {
    // Files look like: "user/<UID>/path/to/file.txt"
    match /user/{userId}/{allPaths=**} {
      allow read, write: if request.auth != null && request.auth.uid == userId;
    }
  }
}

การเข้าถึงแบบสาธารณะและส่วนตัวแบบผสม

กฎนี้อนุญาตให้ทุกคนอ่านชุดข้อมูลได้ แต่จำกัดความสามารถในการ สร้างหรือแก้ไขข้อมูลตามเส้นทางที่กำหนดไปยังเจ้าของเนื้อหาที่ตรวจสอบสิทธิ์แล้วเท่านั้น

เมื่อกฎนี้ทำงาน: กฎนี้ทำงานได้ดีกับแอปที่กำหนดให้เป็นแบบสาธารณะ ที่อ่านได้ แต่ต้องจำกัดการเข้าถึงการแก้ไของค์ประกอบเหล่านั้น" เช่น แอปแชทหรือบล็อก

กรณีที่กฎนี้ใช้ไม่ได้: เช่นเดียวกับกฎสำหรับเจ้าของเนื้อหาเท่านั้น ชุดกฎนี้จะใช้ไม่ได้เมื่อผู้ใช้หลายคนต้องแก้ไขข้อมูลเดียวกัน ผู้ใช้จะ ซึ่งท้ายที่สุดแล้วจะเขียนทับข้อมูลของกันและกัน

วิธีตั้งค่ากฎนี้: สร้างกฎที่เปิดใช้สิทธิ์การอ่านสำหรับผู้ใช้ทั้งหมด (หรือผู้ใช้ที่ได้รับการตรวจสอบสิทธิ์ทั้งหมด) และยืนยันว่าข้อมูลการเขียนของผู้ใช้เป็นเจ้าของ

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow public read access, but only content owners can write
    match /some_collection/{document} {
      allow read: if true
      allow create: if request.auth.uid == request.resource.data.author_uid;
      allow update, delete: if request.auth.uid == resource.data.author_uid;
    }
  }
}

Realtime Database

{
// Allow anyone to read data, but only authenticated content owners can
// make changes to their data

  "rules": {
    "some_path": {
      "$uid": {
        ".read": true,
        // or ".read": "auth.uid !== null" for only authenticated users
        ".write": "auth.uid === $uid"
      }
    }
  }
}

Cloud Storage

service firebase.storage {
  match /b/{bucket}/o {
    // Files look like: "user/<UID>/path/to/file.txt"
    match /user/{userId}/{allPaths=**} {
      allow read;
      allow write: if request.auth.uid == userId;
    }
  }
}

การเข้าถึงตามแอตทริบิวต์และตามบทบาท

เพื่อให้กฎเหล่านี้ทำงานได้ คุณต้องกำหนดและกำหนดแอตทริบิวต์ให้กับผู้ใช้ใน Firebase Security Rules ตรวจสอบคำขอกับข้อมูลจากฐานข้อมูลหรือไฟล์ของคุณ ข้อมูลเมตาเพื่อยืนยันหรือปฏิเสธการเข้าถึง

เมื่อกฎนี้ทำงาน: หากคุณกำลังมอบหมายบทบาทให้กับผู้ใช้ กฎนี้จะ การจำกัดการเข้าถึงตามบทบาทหรือกลุ่มผู้ใช้เฉพาะทำได้ง่าย เช่น หากจัดเก็บคะแนน คุณสามารถกำหนดระดับการเข้าถึงที่แตกต่างกันให้กับกลุ่ม "นักเรียน" (อ่านเนื้อหาเท่านั้น) กลุ่ม "ครู" (อ่านและเขียนในวิชา) และกลุ่ม "ครูใหญ่" (อ่านเนื้อหาทั้งหมด)

เมื่อกฎนี้ไม่ทำงาน: ใน Realtime Database และ Cloud Storage กฎของคุณ ไม่สามารถใช้ประโยชน์จากเมธอด get() ที่กฎ Cloud Firestore นำมาใช้ได้ คุณจึงต้องจัดโครงสร้างฐานข้อมูลหรือข้อมูลเมตาของไฟล์ให้ แอตทริบิวต์ที่คุณใช้ในกฎ

วิธีตั้งค่ากฎนี้: ใน Cloud Firestore ให้ใส่ช่องใน เอกสารที่คุณอ่านได้ จากนั้นก็จัดโครงสร้างกฎให้อ่าน และให้สิทธิ์เข้าถึงอย่างมีเงื่อนไข ใน Realtime Database ให้สร้างเส้นทางข้อมูลที่ กำหนดผู้ใช้แอปและมอบบทบาทในโหนดย่อยให้แก่ผู้ใช้

คุณยังสามารถตั้งค่าการอ้างสิทธิ์ที่กำหนดเองใน Authentication ได้ด้วย แล้วดึงข้อมูลนั้นจาก auth.token ตัวแปรใน Firebase Security Rules ใดก็ได้

แอตทริบิวต์และบทบาทที่กำหนดโดยข้อมูล

กฎเหล่านี้ใช้ได้ใน Cloud Firestore และ Realtime Database เท่านั้น

Cloud Firestore

โปรดทราบว่าทุกครั้งที่กฎมีการอ่าน เช่น กฎด้านล่าง ระบบจะเรียกเก็บเงินจากคุณสำหรับการดำเนินการอ่านใน Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    // For attribute-based access control, Check a boolean `admin` attribute
    allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true;
    allow read: true;

    // Alterntatively, for role-based access, assign specific roles to users
    match /some_collection/{document} {
     allow read: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Reader"
     allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Writer"
   }
  }
}

Realtime Database

{
  "rules": {
    "some_path": {
      "${subpath}": {
        //
        ".write": "root.child('users').child(auth.uid).child('role').val() === 'admin'",
        ".read": true
      }
    }
  }
}

แอตทริบิวต์และบทบาทของการอ้างสิทธิ์ที่กำหนดเอง

หากต้องการใช้กฎเหล่านี้ ให้ตั้งค่าการอ้างสิทธิ์ที่กำหนดเอง ใน Firebase Authentication แล้วใช้ประโยชน์จากการอ้างสิทธิ์ในกฎของคุณ

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    // For attribute-based access control, check for an admin claim
    allow write: if request.auth.token.admin == true;
    allow read: true;

    // Alterntatively, for role-based access, assign specific roles to users
    match /some_collection/{document} {
     allow read: if request.auth.token.reader == "true";
     allow write: if request.auth.token.writer == "true";
   }
  }
}

Realtime Database

{
  "rules": {
    "some_path": {
      "$uid": {
        // Create a custom claim for each role or group
        // you want to leverage
        ".write": "auth.uid !== null && auth.token.writer === true",
        ".read": "auth.uid !== null && auth.token.reader === true"
      }
    }
  }
}

Cloud Storage

service firebase.storage {
  // 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;
  }
}

แอตทริบิวต์ขององค์กร

หากต้องการใช้กฎเหล่านี้ ให้ตั้งค่า Multitenancy ใน Google Cloud Identity Platform (GCIP) แล้วใช้ประโยชน์จากกลุ่มผู้ใช้ในกฎ ตัวอย่างต่อไปนี้อนุญาตให้เขียน จากผู้ใช้ในกลุ่มผู้ใช้ที่เฉพาะเจาะจง เช่น tenant2-m6tyz

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    // For tenant-based access control, check for a tenantID
    allow write: if request.auth.token.firebase.tenant == 'tenant2-m6tyz';
    allow read: true;
  }
}

Realtime Database

{
  "rules": {
    "some_path": {
      "$uid": {
        // Only allow reads and writes if user belongs to a specific tenant
        ".write": "auth.uid !== null && auth.token.firebase.tenant === 'tenant2-m6tyz'",
        ".read": "auth.uid !== null
      }
    }
  }
}

Cloud Storage

service firebase.storage {
  // Only allow reads and writes if user belongs to a specific tenant
  match /files/{tenantId}/{fileName} {
    allow read: if request.auth != null;
    allow write: if request.auth.token.firebase.tenant == tenantId;
  }
}