การจัดโครงสร้างกฎความปลอดภัยของ 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

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

เวอร์ชั่น 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 ประมวลผลซอร์สและทำให้ใช้งานได้ที่ส่วนหลัง

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