Catch up on highlights from Firebase at Google I/O 2023. Learn more

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

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

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

ประกาศบริการและฐานข้อมูล

กฎความปลอดภัยของ Cloud Firestore จะเริ่มต้นด้วยการประกาศต่อไปนี้เสมอ:

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

การประกาศ service cloud.firestore กำหนดขอบเขตของกฎเป็น Cloud Firestore เพื่อป้องกันความขัดแย้งระหว่างกฎความปลอดภัยของ Cloud Firestore และกฎสำหรับผลิตภัณฑ์อื่นๆ เช่น 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 /cities/SF หรือใช้อักขระตัวแทนเพื่อชี้ไปยังเอกสารใดๆ ในเส้นทางที่ระบุ เช่นเดียวกับใน match /cities/{city}

ในตัวอย่างข้างต้น คำสั่งการจับคู่ใช้รูปแบบไวด์การ์ด {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 สัญลักษณ์ตัวแทนแบบเรียกซ้ำจะตรงกับรายการเส้นทางอย่างน้อยหนึ่งรายการ ไม่ตรงกับพาธว่าง ดังนั้น match /cities/{city}/{document=**} จับคู่เอกสารในคอลเล็กชันย่อยแต่ไม่ใช่ในคอลเล็กชัน cities ในขณะที่ match /cities/{document=**} จับคู่เอกสารทั้งสองใน คอลเลกชัน cities และคอลเลกชันย่อย

สัญลักษณ์ตัวแทนแบบเรียกซ้ำต้องมาที่ส่วนท้ายของคำสั่งการแข่งขัน

เวอร์ชัน 2

ในกฎความปลอดภัยเวอร์ชัน 2 สัญลักษณ์ตัวแทนแบบเรียกซ้ำจะตรงกับรายการเส้นทางตั้งแต่ศูนย์ขึ้นไป 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>;
    }
  }
}

คุณสามารถมีไวด์การ์ดแบบเรียกซ้ำได้สูงสุดหนึ่งรายการต่อคำสั่งจับคู่ แต่ในเวอร์ชัน 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 มากกว่าหนึ่งคำสั่ง ในกรณีที่ 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 จะได้รับอนุญาต เนื่องจากกฎข้อที่สองเป็น 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 (ไม่อนุญาต)
จำนวนนิพจน์สูงสุดที่ประเมินต่อคำขอ 1,000
ขนาดสูงสุดของชุดกฎ ชุดกฎต้องเป็นไปตามขีดจำกัดขนาดสองข้อ:
  • ขีดจำกัด 256 KB สำหรับขนาดของแหล่งข้อความชุดกฎที่เผยแพร่จากคอนโซล Firebase หรือจาก CLI โดยใช้ firebase deploy
  • ขีดจำกัด 250 KB สำหรับขนาดของชุดกฎที่คอมไพล์ซึ่งส่งผลให้เมื่อ Firebase ประมวลผลซอร์สและทำให้แอ็คทีฟบนแบ็คเอนด์

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