วิธีการทำงานของกฎความปลอดภัย

ความปลอดภัยอาจเป็นหนึ่งในที่ซับซ้อนที่สุดของปริศนาการพัฒนาแอป ในแอปพลิเคชันส่วนใหญ่ นักพัฒนาซอฟต์แวร์จะต้องสร้างและเรียกใช้เซิร์ฟเวอร์ที่ จัดการการตรวจสอบสิทธิ์ (ผู้ใช้คือใคร) และการให้สิทธิ์ (สิ่งที่ผู้ใช้ทําได้)

Firebase Security Rules นำเลเยอร์กลาง (เซิร์ฟเวอร์) ออกและให้คุณระบุเส้นทางแบบอิงตามเส้นทางได้ สิทธิ์สำหรับลูกค้าที่เชื่อมต่อกับข้อมูลของคุณโดยตรง ใช้คู่มือนี้เพื่อ ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีใช้กฎกับคำขอที่เข้ามาใหม่

เลือกผลิตภัณฑ์เพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับกฎ

Cloud Firestore

โครงสร้างพื้นฐาน

Firebase Security Rules ใน Cloud Firestore และ Cloud Storage ใช้โครงสร้างต่อไปนี้และ ไวยากรณ์:

service <<name>> {
  // Match the resource path.
  match <<path>> {
    // Allow the request if the following conditions are true.
    allow <<methods>> : if <<condition>>
  }
}

แนวคิดหลักต่อไปนี้เป็นสิ่งสำคัญที่ควรทำความเข้าใจในการสร้างกฎ:

  • คำขอ: เมธอดหรือเมธอดในคำสั่ง allow สิ่งเหล่านี้คือ วิธีการที่คุณอนุญาตให้เรียกใช้ เมธอดมาตรฐานได้แก่ get, list create, update และ delete วิธีการอำนวยความสะดวกของ read และ write เปิดใช้สิทธิ์การอ่านและเขียนแบบกว้างบนฐานข้อมูลหรือเส้นทางพื้นที่เก็บข้อมูลที่ระบุ
  • เส้นทาง: ตำแหน่งของฐานข้อมูลหรือตำแหน่งพื้นที่เก็บข้อมูล ซึ่งแสดงเป็น เส้นทาง URI
  • กฎ: คำสั่ง allow ซึ่งมีเงื่อนไขที่อนุญาต หากประเมินเป็น "จริง"

กฎความปลอดภัยเวอร์ชัน 2

กฎความปลอดภัย Firebase เวอร์ชัน 2 ตั้งแต่เดือนพฤษภาคม 2019 เป็นต้นไป พร้อมใช้งาน กฎเวอร์ชัน 2 จะเปลี่ยนลักษณะการทำงานของ recursive ไวลด์การ์ด {name=**} คุณต้องใช้เวอร์ชัน 2 หากมีแผนที่จะ ใช้การค้นหากลุ่มคอลเล็กชัน คุณต้องเลือกใช้ เวอร์ชัน 2 โดยทำให้ rules_version = '2'; เป็นบรรทัดแรกในการรักษาความปลอดภัยของคุณ กฎ:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {

เส้นทางที่ตรงกัน

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

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

คอลเล็กชันย่อยที่ตรงกัน

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

Cloud Storage

โครงสร้างพื้นฐาน

Firebase Security Rules ใน Cloud Firestore และ Cloud Storage ใช้โครงสร้างต่อไปนี้และ ไวยากรณ์:

service <<name>> {
  // Match the resource path.
  match <<path>> {
    // Allow the request if the following conditions are true.
    allow <<methods>> : if <<condition>>
  }
}

แนวคิดหลักต่อไปนี้เป็นสิ่งสำคัญที่ควรทำความเข้าใจในการสร้างกฎ:

  • คำขอ: เมธอดหรือเมธอดในคำสั่ง allow สิ่งเหล่านี้คือ วิธีการที่คุณอนุญาตให้เรียกใช้ เมธอดมาตรฐานได้แก่ get, list create, update และ delete วิธีการอำนวยความสะดวกของ read และ write เปิดใช้สิทธิ์การอ่านและเขียนแบบกว้างบนฐานข้อมูลหรือเส้นทางพื้นที่เก็บข้อมูลที่ระบุ
  • เส้นทาง: ตำแหน่งของฐานข้อมูลหรือตำแหน่งพื้นที่เก็บข้อมูล ซึ่งแสดงเป็น เส้นทาง URI
  • กฎ: คำสั่ง allow ซึ่งมีเงื่อนไขที่อนุญาต หากประเมินเป็น "จริง"

เส้นทางที่ตรงกัน

Cloud Storage Security Rules match เส้นทางของไฟล์ที่ใช้เข้าถึงไฟล์ Cloud Storage กฎสามารถmatchเส้นทางที่แน่นอนหรือเส้นทางไวลด์การ์ด และ สามารถซ้อนกันได้ด้วย หากไม่มีกฎที่ตรงกันที่อนุญาตเมธอดคำขอ หรือ ประเมินได้เป็น false คำขอถูกปฏิเสธ

เหมือนกันทุกประการ

// Exact match for "images/profilePhoto.png"
match /images/profilePhoto.png {
  allow write: if <condition>;
}

// Exact match for "images/croppedProfilePhoto.png"
match /images/croppedProfilePhoto.png {
  allow write: if <other_condition>;
}

รายการที่ตรงกันที่ซ้อนกัน

// Partial match for files that start with "images"
match /images {
  // Exact match for "images/profilePhoto.png"
  match /profilePhoto.png {
    allow write: if <condition>;
  }

  // Exact match for "images/croppedProfilePhoto.png"
  match /croppedProfilePhoto.png {
    allow write: if <other_condition>;
  }
}

การจับคู่ไวลด์การ์ด

นอกจากนี้ยังใช้กฎเพื่อmatchรูปแบบโดยใช้ไวลด์การ์ดได้ด้วย ไวลด์การ์ดคือ ตัวแปรที่มีชื่อซึ่งแสดงสตริงเดียว เช่น profilePhoto.png หรือกลุ่มเส้นทางหลายกลุ่ม เช่น images/profilePhoto.png

ไวลด์การ์ดสร้างขึ้นโดยการเพิ่มวงเล็บปีกการอบๆ ชื่อไวลด์การ์ด เช่น {string} คุณสามารถประกาศไวลด์การ์ดของกลุ่มหลายกลุ่มได้โดยการเพิ่ม =** ลงในส่วน ชื่อไวลด์การ์ด เช่น {path=**}:

// Partial match for files that start with "images"
match /images {
  // Exact match for "images/*"
  // e.g. images/profilePhoto.png is matched
  match /{imageId} {
    // This rule only matches a single path segment (*)
    // imageId is a string that contains the specific segment matched
    allow read: if <condition>;
  }

  // Exact match for "images/**"
  // e.g. images/users/user:12345/profilePhoto.png is matched
  // images/profilePhoto.png is also matched!
  match /{allImages=**} {
    // This rule matches one or more path segments (**)
    // allImages is a path that contains all segments matched
    allow read: if <other_condition>;
  }
}

หากมีกฎหลายข้อตรงกับไฟล์ ผลลัพธ์จะเป็น OR ของผลลัพธ์ทั้งหมด และการประเมินกฎ กล่าวคือ หากกฎใดตรงกับไฟล์ประเมินผลเป็น true ผลลัพธ์คือ true

ในกฎข้างต้น ไฟล์ "images/profilePhoto.png" สามารถอ่านได้ในกรณีต่อไปนี้ condition หรือ other_condition ประเมินผลเป็น "จริง" ขณะที่ไฟล์ "images/users/user:12345/profilePhoto.png" จะขึ้นอยู่กับผลลัพธ์ของ other_condition

อ้างอิงตัวแปรไวลด์การ์ดได้จากภายในไฟล์ที่ระบุ match ชื่อหรือเส้นทางการให้สิทธิ์:

// Another way to restrict the name of a file
match /images/{imageId} {
  allow read: if imageId == "profilePhoto.png";
}

Cloud Storage Security Rules ไม่ต่อเนื่อง และจะมีการประเมินกฎเฉพาะเมื่อ เส้นทางคำขอตรงกับเส้นทางที่มีกฎที่ระบุ

ขอการประเมิน

ระบบจะประเมินการอัปโหลด ดาวน์โหลด การเปลี่ยนแปลงข้อมูลเมตา และการลบโดยใช้ ส่งเงินจำนวน request ไปยัง Cloud Storage แล้ว ตัวแปร request ประกอบด้วยค่า เส้นทางไฟล์ที่ดำเนินการตามคำขอ เวลาที่คำขอ ที่ได้รับ และค่า resource ใหม่หากคำขอเป็นการเขียน ส่วนหัว HTTP รวมทั้งสถานะการตรวจสอบสิทธิ์

ออบเจ็กต์ request ยังมีรหัสที่ไม่ซ้ำกันของผู้ใช้และ เพย์โหลด Firebase Authentication ในออบเจ็กต์ request.auth ซึ่งจะ ซึ่งอธิบายเพิ่มเติมในการตรวจสอบสิทธิ์ ของเอกสาร

รายการที่พักทั้งหมดในออบเจ็กต์ request แสดงอยู่ด้านล่าง

พร็อพเพอร์ตี้ ประเภท คำอธิบาย
auth แมป<สตริง, สตริง> เมื่อผู้ใช้เข้าสู่ระบบ ให้ระบุ uid, รหัสที่ไม่ซ้ำกันของผู้ใช้ และ token แผนที่แสดงการอ้างสิทธิ์ JWT Firebase Authentication รายการ มิฉะนั้น ระบบจะ null
params แมป<สตริง, สตริง> แผนที่ที่มีพารามิเตอร์การค้นหาของคำขอ
path เส้นทาง path ที่แสดงเส้นทางที่มีการส่งคำขอ แสดงเมื่อ
resource แมป<สตริง, สตริง> ค่าทรัพยากรใหม่ แสดงเฉพาะในคำขอ write เท่านั้น
time การประทับเวลา การประทับเวลาที่แสดงถึงเวลาของเซิร์ฟเวอร์ที่มีการประเมินคำขอ

การประเมินทรัพยากร

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

Firebase Security Rules สำหรับ Cloud Storage จะระบุข้อมูลเมตาของไฟล์ใน resource ซึ่งมีคู่คีย์/ค่าของข้อมูลเมตาที่แสดงใน Cloud Storage ออบเจ็กต์ ตรวจสอบพร็อพเพอร์ตี้เหล่านี้ได้ใน read หรือ write คำขอเพื่อตรวจสอบความสมบูรณ์ของข้อมูล

ในคำขอ write (เช่น การอัปโหลด อัปเดตข้อมูลเมตา และการลบ) ใน นอกเหนือจากออบเจ็กต์ resource ซึ่งมีข้อมูลเมตาของไฟล์ ที่มีอยู่ในเส้นทางคำขออยู่แล้ว คุณยังสามารถใช้ request.resource ซึ่งมีข้อมูลเมตาไฟล์บางส่วนที่จะ เขียนหากการเขียนได้รับอนุญาต คุณใช้ค่า 2 ค่านี้เพื่อตรวจสอบข้อมูล ความสมบูรณ์หรือบังคับใช้ข้อจำกัดของแอปพลิเคชัน เช่น ประเภทไฟล์หรือขนาดไฟล์

รายการที่พักทั้งหมดในออบเจ็กต์ resource แสดงอยู่ด้านล่าง

พร็อพเพอร์ตี้ ประเภท คำอธิบาย
name สตริง ชื่อเต็มของออบเจ็กต์
bucket สตริง ชื่อของที่เก็บข้อมูลที่มีออบเจ็กต์นี้
generation int Google Cloud Storage การสร้างออบเจ็กต์ของออบเจ็กต์นี้
metageneration int Google Cloud Storage Metageneration ของออบเจ็กต์นี้
size int ขนาดของออบเจ็กต์ในหน่วยไบต์
timeCreated การประทับเวลา การประทับเวลาที่แสดงถึงเวลาที่สร้างออบเจ็กต์
updated การประทับเวลา การประทับเวลาที่แสดงถึงเวลาที่อัปเดตออบเจ็กต์ครั้งล่าสุด
md5Hash สตริง แฮช MD5 ของออบเจ็กต์
crc32c สตริง แฮช crc32c ของออบเจ็กต์
etag สตริง eTag ที่เชื่อมโยงกับออบเจ็กต์นี้
contentDisposition สตริง การจัดการเนื้อหาที่เชื่อมโยงกับออบเจ็กต์นี้
contentEncoding สตริง การเข้ารหัสเนื้อหาที่เชื่อมโยงกับออบเจ็กต์นี้
contentLanguage สตริง ภาษาของเนื้อหาที่เชื่อมโยงกับออบเจ็กต์นี้
contentType สตริง ประเภทเนื้อหาที่เชื่อมโยงกับออบเจ็กต์นี้
metadata แมป<สตริง, สตริง> คู่คีย์/ค่าของข้อมูลเมตาที่กำหนดเองเพิ่มเติมที่นักพัฒนาซอฟต์แวร์ระบุ

request.resource มีข้อมูลทั้งหมดนี้ ยกเว้น generation metageneration, etag, timeCreated และ updated

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

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

ขีดจำกัด รายละเอียด
จำนวนสูงสุดคือ firestore.exists() และ firestore.get() สายต่อคำขอ

2 สำหรับคำขอเอกสารรายการเดียวและคำขอคำค้นหา

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

การเรียกการเข้าถึงเอกสารเดียวกันอาจถูกเก็บในแคช และการเรียกในแคช จะไม่นับรวมในขีดจำกัด

ตัวอย่างแบบเต็ม

เมื่อนำทั้งหมดมารวมกัน คุณก็จะได้สร้างกฎตัวอย่างที่สมบูรณ์สำหรับรูปภาพหนึ่งๆ โซลูชันพื้นที่เก็บข้อมูล

service firebase.storage {
 match /b/{bucket}/o {
   match /images {
     // Cascade read to any image type at any path
     match /{allImages=**} {
       allow read;
     }

     // Allow write files to the path "images/*", subject to the constraints:
     // 1) File is less than 5MB
     // 2) Content type is an image
     // 3) Uploaded content type matches existing content type
     // 4) File name (stored in imageId wildcard variable) is less than 32 characters
     match /{imageId} {
       allow write: if request.resource.size < 5 * 1024 * 1024
                    && request.resource.contentType.matches('image/.*')
                    && request.resource.contentType == resource.contentType
                    && imageId.size() < 32
     }
   }
 }
}

Realtime Database

โครงสร้างพื้นฐาน

ใน Realtime Database Firebase Security Rules ประกอบด้วยนิพจน์ที่เหมือน JavaScript ที่มีอยู่ใน เอกสาร JSON

โดยใช้ไวยากรณ์ต่อไปนี้

{
  "rules": {
    "<<path>>": {
    // Allow the request if the condition for each method is true.
      ".read": <<condition>>,
      ".write": <<condition>>,
      ".validate": <<condition>>
    }
  }
}

มีองค์ประกอบพื้นฐาน 3 อย่างในกฎดังนี้

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

วิธีใช้กฎกับเส้นทาง

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

โดยพิจารณากฎต่อไปนี้

{
  "rules": {
     "foo": {
        // allows read to /foo/*
        ".read": "data.child('baz').val() === true",
        "bar": {
          // ignored, since read was allowed already
          ".read": false
        }
     }
  }
}

โครงสร้างการรักษาความปลอดภัยนี้ช่วยให้อ่าน /bar/ ได้ตั้งแต่เมื่อใด /foo/ มีย่อย baz ที่มีค่า true กฎ ".read": false ภายใต้ /foo/bar/ ไม่มี ที่นี่ เนื่องจากเส้นทางย่อยไม่สามารถเพิกถอนการเข้าถึงได้

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

อย่างไรก็ตาม กฎ .validate รายการจะไม่เรียงซ้อนกัน กฎการตรวจสอบทั้งหมด การเขียนจะต้องตรงตามลำดับชั้นในทุกระดับเพื่อให้เขียนได้

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

{
  "rules": {
    "records": {
      "rec1": {
        ".read": true
      },
      "rec2": {
        ".read": false
      }
    }
  }
}

หากคุณไม่เข้าใจว่ากฎจะได้รับการประเมินในเชิงอะตอม ก็อาจดูเหมือน เช่น การดึงข้อมูลเส้นทาง /records/ จะแสดงผล rec1 แต่ไม่ใช่ rec2 อย่างไรก็ตาม ผลลัพธ์ตามจริงเป็นข้อผิดพลาด

JavaScript
var db = firebase.database();
db.ref("records").once("value", function(snap) {
  // success method is not called
}, function(err) {
  // error callback triggered with PERMISSION_DENIED
});
Objective-C
หมายเหตุ: ผลิตภัณฑ์ Firebase นี้ไม่พร้อมใช้งานในเป้าหมาย App Clip
FIRDatabaseReference *ref = [[FIRDatabase database] reference];
[[_ref child:@"records"] observeSingleEventOfType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot *snapshot) {
  // success block is not called
} withCancelBlock:^(NSError * _Nonnull error) {
  // cancel block triggered with PERMISSION_DENIED
}];
Swift
หมายเหตุ: ผลิตภัณฑ์ Firebase นี้ไม่พร้อมใช้งานในเป้าหมาย App Clip
var ref = FIRDatabase.database().reference()
ref.child("records").observeSingleEventOfType(.Value, withBlock: { snapshot in
    // success block is not called
}, withCancelBlock: { error in
    // cancel block triggered with PERMISSION_DENIED
})
Java
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("records");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot snapshot) {
    // success method is not called
  }

  @Override
  public void onCancelled(FirebaseError firebaseError) {
    // error callback triggered with PERMISSION_DENIED
  });
});
REST
curl https://docs-examples.firebaseio.com/rest/records/
# response returns a PERMISSION_DENIED error

เนื่องจากการดำเนินการอ่านที่ /records/ เป็นแบบอะตอม และไม่มีกฎการอ่านที่ให้สิทธิ์เข้าถึงข้อมูลทั้งหมดภายใต้ /records/ การดำเนินการนี้จะแสดงข้อผิดพลาด PERMISSION_DENIED หากเราประเมินกฎนี้ในเครื่องจำลองความปลอดภัยในคอนโซล Firebase จะพบว่าการดำเนินการอ่านถูกปฏิเสธ

Attempt to read /records with auth=Success(null)
    /
    /records

No .read rule allowed the operation.
Read was denied.

การดำเนินการนี้ถูกปฏิเสธเนื่องจากไม่มีกฎการอ่านที่อนุญาตให้เข้าถึงเส้นทาง /records/ แต่โปรดทราบว่ากฎสำหรับ rec1 ไม่ได้รับการประเมินเนื่องจากไม่ได้อยู่ในเส้นทางที่เราร้องขอ หากต้องการดึงข้อมูล rec1 เราจะต้องเข้าถึงโดยตรง

JavaScript
var db = firebase.database();
db.ref("records/rec1").once("value", function(snap) {
  // SUCCESS!
}, function(err) {
  // error callback is not called
});
Objective-C
หมายเหตุ: ผลิตภัณฑ์ Firebase นี้ไม่พร้อมใช้งานในเป้าหมาย App Clip
FIRDatabaseReference *ref = [[FIRDatabase database] reference];
[[ref child:@"records/rec1"] observeSingleEventOfType:FEventTypeValue withBlock:^(FIRDataSnapshot *snapshot) {
    // SUCCESS!
}];
Swift
หมายเหตุ: ผลิตภัณฑ์ Firebase นี้ไม่พร้อมใช้งานในเป้าหมาย App Clip
var ref = FIRDatabase.database().reference()
ref.child("records/rec1").observeSingleEventOfType(.Value, withBlock: { snapshot in
    // SUCCESS!
})
Java
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("records/rec1");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot snapshot) {
    // SUCCESS!
  }

  @Override
  public void onCancelled(FirebaseError firebaseError) {
    // error callback is not called
  }
});
REST
curl https://docs-examples.firebaseio.com/rest/records/rec1
# SUCCESS!

ตัวแปรสถานที่ตั้ง

Realtime Database Rules รองรับ $location ตัวแปรที่ตรงกับกลุ่มเส้นทาง ใช้คำนำหน้า $ ที่ด้านหน้าเส้นทาง กลุ่มเพื่อจับคู่กฎกับโหนดย่อยตลอดเส้นทาง

  {
    "rules": {
      "rooms": {
        // This rule applies to any child of /rooms/, the key for each room id
        // is stored inside $room_id variable for reference
        "$room_id": {
          "topic": {
            // The room's topic can be changed if the room id has "public" in it
            ".write": "$room_id.contains('public')"
          }
        }
      }
    }
  }

คุณจะใช้ $variable คู่ขนานกับเส้นทางคงที่ก็ได้

  {
    "rules": {
      "widget": {
        // a widget can have a title or color attribute
        "title": { ".validate": true },
        "color": { ".validate": true },

        // but no other child paths are allowed
        // in this case, $other means any key excluding "title" and "color"
        "$other": { ".validate": false }
      }
    }
  }