การจัดโครงสร้างกฎความปลอดภัยของ Cloud Firestore

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

คู่มือนี้จะอธิบายไวยากรณ์และโครงสร้างพื้นฐานของกฎความปลอดภัย รวมไวยากรณ์นี้กับเงื่อนไขของกฎความปลอดภัยเพื่อสร้างชุดกฎที่สมบูรณ์

การประกาศเกี่ยวกับบริการและฐานข้อมูล

Cloud Firestore Security Rules ต้องเริ่มต้นด้วยการประกาศต่อไปนี้เสมอ

service cloud.firestore {
  match /databases/{database}/documents {
    // ...
  }
}

การประกาศ service cloud.firestore จะกำหนดขอบเขตของกฎเป็น Cloud Firestore เพื่อป้องกันความขัดแย้งระหว่าง Cloud Firestore Security Rules กับ กฎสำหรับผลิตภัณฑ์อื่นๆ เช่น Cloud Storage

การประกาศ match /databases/{database}/documents ระบุว่ากฎควร ตรงกับฐานข้อมูล Cloud Firestore ใดก็ได้ในโปรเจ็กต์ ปัจจุบันแต่ละโปรเจ็กต์ มีฐานข้อมูลเพียงรายการเดียวชื่อ (default)

กฎการอ่าน/เขียนพื้นฐาน

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

service cloud.firestore {
  match /databases/{database}/documents {

    // Match any document in the 'cities' collection
    match /cities/{city} {
      allow read: if <condition>;
      allow write: if <condition>;
    }
  }
}

คำสั่งจับคู่ทั้งหมดควรชี้ไปยังเอกสาร ไม่ใช่คอลเล็กชัน คำสั่ง match สามารถชี้ไปยังเอกสารที่เฉพาะเจาะจงได้ เช่น match /cities/SF หรือใช้ไวลด์การ์ด เพื่อชี้ไปยังเอกสารใดก็ได้ในเส้นทางที่ระบุ เช่น match /cities/{city}

ในตัวอย่างข้างต้น คำสั่ง match ใช้ไวยากรณ์ไวลด์การ์ด {city} ซึ่งหมายความว่ากฎจะมีผลกับเอกสารใดก็ตามในคอลเล็กชัน cities เช่น /cities/SF หรือ /cities/NYC เมื่อมีการประเมินallowนิพจน์ในคำสั่งที่ตรงกัน ตัวแปร city จะเปลี่ยนเป็นชื่อเอกสารเมือง เช่น SF หรือ NYC

การดำเนินการแบบละเอียด

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

กฎ read สามารถแบ่งออกเป็น get และ list ในขณะที่กฎ write สามารถแบ่งออกเป็น create, update และ delete

service cloud.firestore {
  match /databases/{database}/documents {
    // A read rule can be divided into get and list rules
    match /cities/{city} {
      // Applies to single document read requests
      allow get: if <condition>;

      // Applies to queries and collection read requests
      allow list: if <condition>;
    }

    // A write rule can be divided into create, update, and delete rules
    match /cities/{city} {
      // Applies to writes to nonexistent documents
      allow create: if <condition>;

      // Applies to writes to existing documents
      allow update: if <condition>;

      // Applies to delete operations
      allow delete: if <condition>;
    }
  }
}

ข้อมูลแบบลำดับชั้น

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

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

service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city} {
      allow read, write: if <condition>;

        // Explicitly define rules for the 'landmarks' subcollection
        match /landmarks/{landmark} {
          allow read, write: if <condition>;
        }
    }
  }
}

เมื่อซ้อนคำสั่ง match เส้นทางของคำสั่ง match ด้านในจะสัมพันธ์กับเส้นทางของคำสั่ง match ด้านนอกเสมอ ดังนั้นชุดกฎต่อไปนี้ จึงมีความหมายเหมือนกัน

service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city} {
      match /landmarks/{landmark} {
        allow read, write: if <condition>;
      }
    }
  }
}
service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city}/landmarks/{landmark} {
      allow read, write: if <condition>;
    }
  }
}

ไวลด์การ์ดแบบเรียกซ้ำ

หากต้องการให้กฎมีผลกับลำดับชั้นที่ลึกเท่าใดก็ได้ ให้ใช้ไวยากรณ์สัญลักษณ์แทนแบบเรียกซ้ำ {name=**} เช่น

service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the cities collection as well as any document
    // in a subcollection.
    match /cities/{document=**} {
      allow read, write: if <condition>;
    }
  }
}

เมื่อใช้ไวยากรณ์ไวลด์การ์ดแบบเรียกซ้ำ ตัวแปรไวลด์การ์ดจะมีส่วนเส้นทางที่ตรงกันทั้งหมด แม้ว่าเอกสารจะอยู่ในคอลเล็กชันย่อยที่ซ้อนกันลึกก็ตาม ตัวอย่างเช่น กฎที่แสดงด้านบนจะตรงกับเอกสารที่อยู่ใน /cities/SF/landmarks/coit_tower และค่าของตัวแปร document จะเป็น SF/landmarks/coit_tower

อย่างไรก็ตาม โปรดทราบว่าลักษณะการทำงานของไวลด์การ์ดแบบเรียกซ้ำจะขึ้นอยู่กับเวอร์ชันของกฎ

เวอร์ชัน 1

กฎความปลอดภัยจะใช้เวอร์ชัน 1 โดยค่าเริ่มต้น ในเวอร์ชัน 1 ไวลด์การ์ดแบบเรียกซ้ำ จะตรงกับรายการเส้นทางอย่างน้อย 1 รายการ โดยจะไม่ตรงกับเส้นทางที่ว่างเปล่า ดังนั้น match /cities/{city}/{document=**} จะตรงกับเอกสารในคอลเล็กชันย่อย แต่ไม่ตรงกับเอกสารในคอลเล็กชัน cities ในขณะที่ match /cities/{document=**} จะตรงกับเอกสารทั้งในคอลเล็กชัน cities และคอลเล็กชันย่อย

ไวลด์การ์ดแบบเรียกซ้ำต้องอยู่ท้ายคำสั่งที่ตรงกัน

เวอร์ชัน 2

ในกฎความปลอดภัยเวอร์ชัน 2 ไวลด์การ์ดแบบเรียกซ้ำจะจับคู่รายการเส้นทาง 0 รายการขึ้นไป match/cities/{city}/{document=**} จะจับคู่เอกสารในคอลเล็กชันย่อย ทั้งหมด รวมถึงเอกสารในคอลเล็กชัน cities

คุณต้องเลือกใช้เวอร์ชัน 2 โดยเพิ่ม rules_version = '2'; ที่ด้านบนของ กฎความปลอดภัย

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the cities collection as well as any document
    // in a subcollection.
    match /cities/{city}/{document=**} {
      allow read, write: if <condition>;
    }
  }
}

คุณมีไวลด์การ์ดแบบเรียกซ้ำได้มากที่สุด 1 รายการต่อคำสั่งจับคู่ แต่ในเวอร์ชัน 2 คุณวางไวลด์การ์ดนี้ไว้ที่ใดก็ได้ในคำสั่งจับคู่ เช่น

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the songs collection group
    match /{path=**}/songs/{song} {
      allow read, write: if <condition>;
    }
  }
}

หากใช้การค้นหากลุ่มคอลเล็กชัน คุณต้องใช้เวอร์ชัน 2 ดูการรักษาความปลอดภัยให้กับการค้นหากลุ่มคอลเล็กชัน

ข้อความที่ตรงกันซึ่งซ้อนทับกัน

เอกสารอาจตรงกับmatchคำสั่งมากกว่า 1 รายการ ในกรณีที่นิพจน์ allow หลายรายการตรงกับคำขอ ระบบจะอนุญาตให้เข้าถึง หากเงื่อนไขใดเงื่อนไขหนึ่งเป็น true

service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the 'cities' collection.
    match /cities/{city} {
      allow read, write: if false;
    }

    // Matches any document in the 'cities' collection or subcollections.
    match /cities/{document=**} {
      allow read, write: if true;
    }
  }
}

ในตัวอย่างข้างต้น ระบบจะอนุญาตการอ่านและการเขียนทั้งหมดไปยังคอลเล็กชัน cities เนื่องจากกฎที่ 2 เป็น true เสมอ แม้ว่ากฎแรกจะเป็น false เสมอ

ขีดจำกัดของกฎความปลอดภัย

ขณะทำงานกับกฎความปลอดภัย โปรดทราบขีดจำกัดต่อไปนี้

ขีดจำกัด รายละเอียด
จำนวนการเรียก exists(), get() และ getAfter() สูงสุดต่อคำขอ
  • 10 สำหรับคำขอเอกสารเดียวและคำขอการค้นหา
  • 20 สำหรับการอ่านแบบหลายเอกสาร ธุรกรรม และการเขียนแบบเป็นกลุ่ม ขีดจำกัดก่อนหน้านี้ที่ 10 รายการจะมีผลกับการดำเนินการแต่ละครั้งด้วย

    ตัวอย่างเช่น สมมติว่าคุณสร้างคำขอเขียนแบบกลุ่มที่มี การดำเนินการเขียน 3 รายการ และกฎการรักษาความปลอดภัยใช้การเรียกการเข้าถึงเอกสาร 2 รายการ เพื่อตรวจสอบการเขียนแต่ละรายการ ในกรณีนี้ การเขียนแต่ละครั้งจะใช้การเรียกเข้าถึง 2 ครั้งจาก 10 ครั้ง และคำขอเขียนแบบกลุ่มจะใช้การเรียกเข้าถึง 6 ครั้งจาก 20 ครั้ง

หากเกินขีดจำกัดใดขีดจำกัดหนึ่ง ระบบจะแสดงข้อผิดพลาด "ปฏิเสธสิทธิ์"

ระบบอาจแคชการเรียกใช้การเข้าถึงเอกสารบางรายการ และการเรียกใช้ที่แคชจะไม่นับรวมในโควต้า

ความลึกสูงสุดของคำสั่ง match ที่ซ้อนกัน 10
ความยาวเส้นทางสูงสุดในส่วนเส้นทางที่อนุญาตภายในชุดคำสั่ง match ที่ซ้อนกัน 100
จำนวนตัวแปรการบันทึกเส้นทางสูงสุดที่อนุญาตภายในชุดคำสั่ง match ที่ซ้อนกัน 20
ความลึกสูงสุดของการเรียกใช้ฟังก์ชัน 20
จำนวนอาร์กิวเมนต์ของฟังก์ชันสูงสุด 7
จำนวนการเชื่อมโยงตัวแปร let สูงสุดต่อฟังก์ชัน 10
จำนวนการเรียกฟังก์ชันแบบเรียกซ้ำหรือแบบวนซ้ำสูงสุด 0 &lpar;ไม่อนุญาต&rpar;
จำนวนสูงสุดของนิพจน์ที่ประเมินต่อคำขอ 1,000 ราย
ขนาดสูงสุดของชุดกฎ ชุดกฎต้องมีขนาดไม่เกิน 2 ขีดจำกัดต่อไปนี้
  • จำกัดขนาดของแหล่งที่มาของข้อความชุดกฎที่ 256 KB ซึ่งเผยแพร่จากFirebaseคอนโซลหรือจาก CLI โดยใช้ firebase deploy
  • จำกัดขนาดของชุดกฎที่คอมไพล์แล้วซึ่งเป็นผลลัพธ์ที่ได้เมื่อ Firebase ประมวลผลแหล่งที่มาและทำให้ใช้งานได้ในแบ็กเอนด์ที่ 250 KB

ขั้นตอนถัดไป