ภาษากฎความปลอดภัย

กฎความปลอดภัยของ Firebase ใช้ประโยชน์จากภาษาที่กำหนดเองที่ยืดหยุ่น ทรงพลัง ซึ่งรองรับความซับซ้อนและรายละเอียดที่หลากหลาย คุณสามารถทำให้กฎมีความเฉพาะเจาะจงหรือกว้างพอสำหรับแอปของคุณได้ กฎฐานข้อมูลเรียลไทม์ใช้ไวยากรณ์ที่ดูเหมือน JavaScript ในโครงสร้าง JSON กฎ Cloud Firestore และ Cloud Storage ใช้ภาษาที่อิงตาม Common Expression Language (CEL) ที่สร้างบน CEL พร้อม match และ allow คำสั่งที่รองรับการเข้าถึงที่ได้รับแบบมีเงื่อนไข

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

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

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

คลาวด์ไฟร์สโตร์

กฎความปลอดภัยของ Firebase ใน 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 ซึ่งรวมถึงเงื่อนไขที่อนุญาตให้มีการร้องขอหากประเมินว่าเป็นจริง

แต่ละแนวคิดเหล่านี้มีการอธิบายไว้ในรายละเอียดเพิ่มเติมด้านล่าง

การจัดเก็บเมฆ

กฎความปลอดภัยของ Firebase ใน 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 ซึ่งรวมถึงเงื่อนไขที่อนุญาตให้มีการร้องขอหากประเมินว่าเป็นจริง

แต่ละแนวคิดเหล่านี้มีการอธิบายไว้ในรายละเอียดเพิ่มเติมด้านล่าง

ฐานข้อมูลเรียลไทม์

ในฐานข้อมูลเรียลไทม์ กฎความปลอดภัยของ Firebase ประกอบด้วยนิพจน์ที่คล้ายกับ JavaScript ที่มีอยู่ในเอกสาร JSON

พวกเขาใช้ไวยากรณ์ต่อไปนี้:

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

มีองค์ประกอบพื้นฐานสามประการในกฎ:

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

โครงสร้างกฎ

คลาวด์ไฟร์สโตร์

องค์ประกอบพื้นฐานของกฎใน Cloud Firestore และ Cloud Storage มีดังนี้:

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

service ประกอบด้วยบล็อก match ตั้งแต่หนึ่งบล็อกขึ้นไปพร้อมคำสั่ง allow ที่ให้เงื่อนไขในการอนุญาตการเข้าถึงคำขอ ตัวแปร request และ resource พร้อมใช้งานในเงื่อนไขของกฎ ภาษากฎความปลอดภัย Firebase ยังรองรับการประกาศ function ด้วย

เวอร์ชันไวยากรณ์

คำสั่ง syntax ระบุเวอร์ชันของภาษากฎ Firebase ที่ใช้ในการเขียนแหล่งที่มา เวอร์ชันล่าสุดของภาษาคือ v2

rules_version = '2';
service cloud.firestore {
...
}

หากไม่มีการระบุคำสั่ง rules_version กฎของคุณจะได้รับการประเมินโดยใช้กลไก v1

บริการ

การประกาศ service จะกำหนดว่ากฎของคุณใช้กับผลิตภัณฑ์หรือบริการ Firebase ใด คุณสามารถรวมการประกาศ service ได้เพียงรายการเดียวต่อไฟล์ต้นฉบับ

คลาวด์ไฟร์สโตร์

service cloud.firestore {
 // Your 'match' blocks with their corresponding 'allow' statements and
 // optional 'function' declarations are contained here
}

การจัดเก็บเมฆ

service firebase.storage {
  // Your 'match' blocks with their corresponding 'allow' statements and
  // optional 'function' declarations are contained here
}

หากคุณกำลังกำหนดกฎสำหรับทั้ง Cloud Firestore และ Cloud Storage โดยใช้ Firebase CLI คุณจะต้องเก็บรักษากฎเหล่านั้นไว้ในไฟล์แยกกัน

จับคู่

บล็อก match จะประกาศรูปแบบ path ที่ตรงกับเส้นทางสำหรับการดำเนินการที่ร้องขอ ( request.path ขาเข้า) เนื้อความของ match จะต้องมีบล็อกการ match ที่ซ้อนกัน คำสั่ง allow หรือการประกาศ function ตั้งแต่หนึ่งบล็อกขึ้นไป เส้นทางในบล็อก match ที่ซ้อนกันจะสัมพันธ์กับเส้นทางในบล็อก match หลัก

รูปแบบ path เป็นชื่อที่เหมือนไดเร็กทอรีซึ่งอาจมีตัวแปรหรือไวด์การ์ด รูปแบบ path ช่วยให้สามารถจับคู่ส่วนของเส้นทางเดียวและหลายเส้นทางได้ ตัวแปรใดๆ ที่ถูกผูกไว้ใน path จะมองเห็นได้ภายในขอบเขต match หรือขอบเขตที่ซ้อนกันซึ่งมีการประกาศ path

การจับคู่กับรูปแบบ path อาจเป็นบางส่วนหรือทั้งหมด:

  • การจับคู่บางส่วน: รูปแบบ path เป็นการจับคู่คำนำหน้าของ request.path
  • การจับคู่ที่สมบูรณ์: รูปแบบ path ตรงกับทั้ง request.path

เมื่อการแข่งขัน เสร็จสมบูรณ์ แล้ว กฎภายในบล็อกจะได้รับการประเมิน เมื่อทำการจับคู่ บางส่วน กฎ match แบบซ้อนจะถูกทดสอบเพื่อดูว่า path ที่ซ้อนกันจะทำให้การแข่งขัน เสร็จสมบูรณ์ หรือไม่

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

// Given request.path == /example/hello/nested/path the following
// declarations indicate whether they are a partial or complete match and
// the value of any variables visible within the scope.
service firebase.storage {
  // Partial match.
  match /example/{singleSegment} {   // `singleSegment` == 'hello'
    allow write;                     // Write rule not evaluated.
    // Complete match.
    match /nested/path {             // `singleSegment` visible in scope.
      allow read;                    // Read rule is evaluated.
    }
  }
  // Complete match.
  match /example/{multiSegment=**} { // `multiSegment` == /hello/nested/path
    allow read;                      // Read rule is evaluated.
  }
}

ดังตัวอย่างข้างต้น การประกาศ path รองรับตัวแปรต่อไปนี้:

  • ไวลด์การ์ดแบบเซกเมนต์เดียว: ตัวแปรไวด์การ์ดได้รับการประกาศในเส้นทางโดยการล้อมตัวแปรด้วยเครื่องหมายปีกกา: {variable} ตัวแปรนี้สามารถเข้าถึงได้ภายในคำสั่งการ match ใน string
  • ไวด์การ์ดแบบเรียกซ้ำ: ไวด์การ์ดแบบเรียกซ้ำหรือหลายส่วนจะจับคู่ส่วนของเส้นทางหลายส่วนที่อยู่ที่หรือต่ำกว่าเส้นทาง ไวด์การ์ดนี้ตรงกับเส้นทางทั้งหมดที่อยู่ด้านล่างตำแหน่งที่คุณตั้งค่าไว้ คุณสามารถประกาศได้โดยเพิ่มสตริง =** ที่ส่วนท้ายของตัวแปรกลุ่มของคุณ: {variable=**} ตัวแปรนี้สามารถเข้าถึงได้ภายในคำสั่งการ match เป็นวัตถุ path

อนุญาต

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

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

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

service firebase.storage {
  // Allow the requestor to read or delete any resource on a path under the
  // user directory.
  match /users/{userId}/{anyUserFile=**} {
    allow read, delete: if request.auth != null && request.auth.uid == userId;
  }

  // Allow the requestor to create or update their own images.
  // When 'request.method' == 'delete' this rule and the one matching
  // any path under the user directory would both match and the `delete`
  // would be permitted.

  match /users/{userId}/images/{imageId} {
    // Whether to permit the request depends on the logical OR of all
    // matched rules. This means that even if this rule did not explicitly
    // allow the 'delete' the earlier rule would have.
    allow write: if request.auth != null && request.auth.uid == userId && imageId.matches('*.png');
  }
}

วิธี

แต่ละคำสั่ง allow มีวิธีการที่ให้สิทธิ์การเข้าถึงสำหรับการร้องขอที่เข้ามาของวิธีการเดียวกัน

วิธี ประเภทคำขอ
วิธีการที่สะดวกสบาย
read คำขออ่านประเภทใดก็ได้
write คำขอเขียนทุกประเภท
วิธีการมาตรฐาน
get คำขออ่านเอกสารหรือไฟล์เดียว
list อ่านคำขอสำหรับแบบสอบถามและคอลเลกชัน
create เขียนเอกสารหรือไฟล์ใหม่
update เขียนลงในเอกสารฐานข้อมูลที่มีอยู่หรืออัปเดตข้อมูลเมตาของไฟล์
delete ลบข้อมูล

คุณไม่สามารถทับซ้อนวิธีการอ่านในบล็อก match เดียวกันหรือวิธีการเขียนที่ขัดแย้งกันในการประกาศ path เดียวกัน

ตัวอย่างเช่น กฎต่อไปนี้จะล้มเหลว:

service bad.example {
  match /rules/with/overlapping/methods {
    // This rule allows reads to all authenticated users
    allow read: if request.auth != null;

    match another/subpath {
      // This secondary, more specific read rule causes an error
      allow get: if request.auth != null && request.auth.uid == "me";
      // Overlapping write methods in the same path cause an error as well
      allow write: if request.auth != null;
      allow create: if request.auth != null && request.auth.uid == "me";
    }
  }
}

การทำงาน

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

  • ฟังก์ชันสามารถมีคำสั่ง return ได้เพียงคำสั่งเดียว ไม่สามารถมีตรรกะเพิ่มเติมใดๆ ได้ ตัวอย่างเช่น ไม่สามารถดำเนินการวนซ้ำหรือเรียกใช้บริการภายนอกได้
  • ฟังก์ชันต่างๆ สามารถเข้าถึงฟังก์ชันและตัวแปรจากขอบเขตที่กำหนดไว้ได้โดยอัตโนมัติ ตัวอย่างเช่น ฟังก์ชันที่กำหนดภายในขอบเขต service cloud.firestore มีสิทธิ์เข้าถึงตัวแปร resource และฟังก์ชันในตัว เช่น get() และ exists()
  • ฟังก์ชันอาจเรียกใช้ฟังก์ชันอื่นแต่อาจไม่เรียกซ้ำ ความลึกของสแต็กการโทรทั้งหมดถูกจำกัดไว้ที่ 20
  • ในกฎเวอร์ชัน v2 ฟังก์ชันสามารถกำหนดตัวแปรโดยใช้คีย์เวิร์ด let ฟังก์ชันสามารถผูก Let ได้สูงสุด 10 รายการ แต่ต้องลงท้ายด้วยคำสั่ง Return

ฟังก์ชันถูกกำหนดด้วยคีย์เวิร์ดของ function และรับอาร์กิวเมนต์เป็นศูนย์หรือมากกว่า ตัวอย่างเช่น คุณอาจต้องการรวมเงื่อนไขสองประเภทที่ใช้ในตัวอย่างด้านบนเป็นฟังก์ชันเดียว:

service cloud.firestore {
  match /databases/{database}/documents {
    // True if the user is signed in or the requested data is 'public'
    function signedInOrPublic() {
      return request.auth.uid != null || resource.data.visibility == 'public';
    }

    match /cities/{city} {
      allow read, write: if signedInOrPublic();
    }

    match /users/{user} {
      allow read, write: if signedInOrPublic();
    }
  }
}

นี่คือตัวอย่างที่แสดงฟังก์ชันอาร์กิวเมนต์และการมอบหมายให้ ให้คำสั่งมอบหมายต้องคั่นด้วยเครื่องหมายอัฒภาค

function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
  return isAuthor || isAdmin;
}

โปรดทราบว่าการมอบหมาย isAdmin บังคับใช้การค้นหาคอลเลกชันผู้ดูแลระบบอย่างไร สำหรับการประเมินแบบขี้เกียจโดยไม่ต้องมีการค้นหาที่ไม่จำเป็น ให้ใช้ประโยชน์จากลักษณะการลัดวงจรของ && (AND) และ || (OR) การเปรียบเทียบเพื่อเรียกใช้ฟังก์ชันที่สองเฉพาะในกรณีที่ isAuthor แสดงว่าเป็นจริง (สำหรับ && การเปรียบเทียบ) หรือเท็จ (สำหรับ || การเปรียบเทียบ)

function isAdmin(userId) {
  return exists(/databases/$(database)/documents/admins/$(userId));
}
function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  // `||` is short-circuiting; isAdmin called only if isAuthor == false.
  return isAuthor || isAdmin(userId);
}

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

การจัดเก็บเมฆ

องค์ประกอบพื้นฐานของกฎใน Cloud Firestore และ Cloud Storage มีดังนี้:

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

service ประกอบด้วยบล็อก match ตั้งแต่หนึ่งบล็อกขึ้นไปพร้อมคำสั่ง allow ที่ให้เงื่อนไขในการอนุญาตการเข้าถึงคำขอ ตัวแปร request และ resource พร้อมใช้งานในเงื่อนไขของกฎ ภาษากฎความปลอดภัย Firebase ยังรองรับการประกาศ function ด้วย

เวอร์ชันไวยากรณ์

คำสั่ง syntax ระบุเวอร์ชันของภาษากฎ Firebase ที่ใช้ในการเขียนแหล่งที่มา เวอร์ชันล่าสุดของภาษาคือ v2

rules_version = '2';
service cloud.firestore {
...
}

หากไม่มีการระบุคำสั่ง rules_version กฎของคุณจะได้รับการประเมินโดยใช้กลไก v1

บริการ

การประกาศ service จะกำหนดว่ากฎของคุณใช้กับผลิตภัณฑ์หรือบริการ Firebase ใด คุณสามารถรวมการประกาศ service ได้เพียงรายการเดียวต่อไฟล์ต้นฉบับ

คลาวด์ไฟร์สโตร์

service cloud.firestore {
 // Your 'match' blocks with their corresponding 'allow' statements and
 // optional 'function' declarations are contained here
}

การจัดเก็บเมฆ

service firebase.storage {
  // Your 'match' blocks with their corresponding 'allow' statements and
  // optional 'function' declarations are contained here
}

หากคุณกำลังกำหนดกฎสำหรับทั้ง Cloud Firestore และ Cloud Storage โดยใช้ Firebase CLI คุณจะต้องเก็บรักษากฎเหล่านั้นไว้ในไฟล์แยกกัน

จับคู่

บล็อก match จะประกาศรูปแบบ path ที่ตรงกับเส้นทางสำหรับการดำเนินการที่ร้องขอ ( request.path ขาเข้า) เนื้อความของ match จะต้องมีบล็อกการ match ที่ซ้อนกัน คำสั่ง allow หรือการประกาศ function ตั้งแต่หนึ่งบล็อกขึ้นไป เส้นทางในบล็อก match ที่ซ้อนกันจะสัมพันธ์กับเส้นทางในบล็อก match หลัก

รูปแบบ path เป็นชื่อที่เหมือนไดเร็กทอรีซึ่งอาจมีตัวแปรหรือไวด์การ์ด รูปแบบ path ช่วยให้สามารถจับคู่ส่วนของเส้นทางเดียวและหลายเส้นทางได้ ตัวแปรใดๆ ที่ถูกผูกไว้ใน path จะมองเห็นได้ภายในขอบเขต match หรือขอบเขตที่ซ้อนกันซึ่งมีการประกาศ path

การจับคู่กับรูปแบบ path อาจเป็นบางส่วนหรือทั้งหมด:

  • การจับคู่บางส่วน: รูปแบบ path เป็นการจับคู่คำนำหน้าของ request.path
  • การจับคู่ที่สมบูรณ์: รูปแบบ path ตรงกับทั้ง request.path

เมื่อการแข่งขัน เสร็จสมบูรณ์ แล้ว กฎภายในบล็อกจะได้รับการประเมิน เมื่อทำการจับคู่ บางส่วน กฎ match แบบซ้อนจะถูกทดสอบเพื่อดูว่า path ที่ซ้อนกันจะทำให้การแข่งขัน เสร็จสมบูรณ์ หรือไม่

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

// Given request.path == /example/hello/nested/path the following
// declarations indicate whether they are a partial or complete match and
// the value of any variables visible within the scope.
service firebase.storage {
  // Partial match.
  match /example/{singleSegment} {   // `singleSegment` == 'hello'
    allow write;                     // Write rule not evaluated.
    // Complete match.
    match /nested/path {             // `singleSegment` visible in scope.
      allow read;                    // Read rule is evaluated.
    }
  }
  // Complete match.
  match /example/{multiSegment=**} { // `multiSegment` == /hello/nested/path
    allow read;                      // Read rule is evaluated.
  }
}

ดังตัวอย่างข้างต้น การประกาศ path รองรับตัวแปรต่อไปนี้:

  • ไวลด์การ์ดแบบเซกเมนต์เดียว: ตัวแปรไวด์การ์ดได้รับการประกาศในเส้นทางโดยการล้อมตัวแปรด้วยเครื่องหมายปีกกา: {variable} ตัวแปรนี้สามารถเข้าถึงได้ภายในคำสั่งการ match ใน string
  • ไวด์การ์ดแบบเรียกซ้ำ: ไวด์การ์ดแบบเรียกซ้ำหรือหลายส่วนจะจับคู่ส่วนของเส้นทางหลายส่วนที่อยู่ที่หรือต่ำกว่าเส้นทาง ไวด์การ์ดนี้ตรงกับเส้นทางทั้งหมดที่อยู่ด้านล่างตำแหน่งที่คุณตั้งค่าไว้ คุณสามารถประกาศได้โดยเพิ่มสตริง =** ที่ส่วนท้ายของตัวแปรกลุ่มของคุณ: {variable=**} ตัวแปรนี้สามารถเข้าถึงได้ภายในคำสั่งการ match เป็นวัตถุ path

อนุญาต

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

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

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

service firebase.storage {
  // Allow the requestor to read or delete any resource on a path under the
  // user directory.
  match /users/{userId}/{anyUserFile=**} {
    allow read, delete: if request.auth != null && request.auth.uid == userId;
  }

  // Allow the requestor to create or update their own images.
  // When 'request.method' == 'delete' this rule and the one matching
  // any path under the user directory would both match and the `delete`
  // would be permitted.

  match /users/{userId}/images/{imageId} {
    // Whether to permit the request depends on the logical OR of all
    // matched rules. This means that even if this rule did not explicitly
    // allow the 'delete' the earlier rule would have.
    allow write: if request.auth != null && request.auth.uid == userId && imageId.matches('*.png');
  }
}

วิธี

แต่ละคำสั่ง allow มีวิธีการที่ให้สิทธิ์การเข้าถึงสำหรับการร้องขอที่เข้ามาของวิธีการเดียวกัน

วิธี ประเภทคำขอ
วิธีการที่สะดวกสบาย
read คำขออ่านประเภทใดก็ได้
write คำขอเขียนทุกประเภท
วิธีการมาตรฐาน
get คำขออ่านเอกสารหรือไฟล์เดียว
list อ่านคำขอสำหรับแบบสอบถามและคอลเลกชัน
create เขียนเอกสารหรือไฟล์ใหม่
update เขียนลงในเอกสารฐานข้อมูลที่มีอยู่หรืออัปเดตข้อมูลเมตาของไฟล์
delete ลบข้อมูล

คุณไม่สามารถทับซ้อนวิธีการอ่านในบล็อก match เดียวกันหรือวิธีการเขียนที่ขัดแย้งกันในการประกาศ path เดียวกัน

ตัวอย่างเช่น กฎต่อไปนี้จะล้มเหลว:

service bad.example {
  match /rules/with/overlapping/methods {
    // This rule allows reads to all authenticated users
    allow read: if request.auth != null;

    match another/subpath {
      // This secondary, more specific read rule causes an error
      allow get: if request.auth != null && request.auth.uid == "me";
      // Overlapping write methods in the same path cause an error as well
      allow write: if request.auth != null;
      allow create: if request.auth != null && request.auth.uid == "me";
    }
  }
}

การทำงาน

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

  • ฟังก์ชันสามารถมีคำสั่ง return ได้เพียงคำสั่งเดียว ไม่สามารถมีตรรกะเพิ่มเติมใดๆ ได้ ตัวอย่างเช่น ไม่สามารถดำเนินการวนซ้ำหรือเรียกใช้บริการภายนอกได้
  • ฟังก์ชันต่างๆ สามารถเข้าถึงฟังก์ชันและตัวแปรจากขอบเขตที่กำหนดไว้ได้โดยอัตโนมัติ ตัวอย่างเช่น ฟังก์ชันที่กำหนดภายในขอบเขต service cloud.firestore มีสิทธิ์เข้าถึงตัวแปร resource และฟังก์ชันในตัว เช่น get() และ exists()
  • ฟังก์ชันอาจเรียกใช้ฟังก์ชันอื่นแต่อาจไม่เรียกซ้ำ ความลึกของสแต็กการโทรทั้งหมดถูกจำกัดไว้ที่ 20
  • ในกฎเวอร์ชัน v2 ฟังก์ชันสามารถกำหนดตัวแปรโดยใช้คีย์เวิร์ด let ฟังก์ชันสามารถผูก Let ได้สูงสุด 10 รายการ แต่ต้องลงท้ายด้วยคำสั่ง Return

ฟังก์ชันถูกกำหนดด้วยคีย์เวิร์ดของ function และรับอาร์กิวเมนต์เป็นศูนย์หรือมากกว่า ตัวอย่างเช่น คุณอาจต้องการรวมเงื่อนไขสองประเภทที่ใช้ในตัวอย่างด้านบนเป็นฟังก์ชันเดียว:

service cloud.firestore {
  match /databases/{database}/documents {
    // True if the user is signed in or the requested data is 'public'
    function signedInOrPublic() {
      return request.auth.uid != null || resource.data.visibility == 'public';
    }

    match /cities/{city} {
      allow read, write: if signedInOrPublic();
    }

    match /users/{user} {
      allow read, write: if signedInOrPublic();
    }
  }
}

นี่คือตัวอย่างที่แสดงฟังก์ชันอาร์กิวเมนต์และการมอบหมายให้ ให้คำสั่งมอบหมายต้องคั่นด้วยเครื่องหมายอัฒภาค

function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
  return isAuthor || isAdmin;
}

โปรดทราบว่าการมอบหมาย isAdmin บังคับใช้การค้นหาคอลเลกชันผู้ดูแลระบบอย่างไร สำหรับการประเมินแบบขี้เกียจโดยไม่ต้องมีการค้นหาที่ไม่จำเป็น ให้ใช้ประโยชน์จากลักษณะการลัดวงจรของ && (AND) และ || (OR) การเปรียบเทียบเพื่อเรียกใช้ฟังก์ชันที่สองเฉพาะในกรณีที่ isAuthor แสดงว่าเป็นจริง (สำหรับ && การเปรียบเทียบ) หรือเท็จ (สำหรับ || การเปรียบเทียบ)

function isAdmin(userId) {
  return exists(/databases/$(database)/documents/admins/$(userId));
}
function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  // `||` is short-circuiting; isAdmin called only if isAuthor == false.
  return isAuthor || isAdmin(userId);
}

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

ฐานข้อมูลเรียลไทม์

ตามที่ระบุไว้ข้างต้น กฎฐานข้อมูลเรียลไทม์ประกอบด้วยองค์ประกอบพื้นฐานสามประการ ได้แก่ ตำแหน่งฐานข้อมูลที่เป็นมิเรอร์ของโครงสร้าง JSON ของฐานข้อมูล ประเภทคำขอ และเงื่อนไขในการอนุญาตการเข้าถึง

ที่ตั้งฐานข้อมูล

โครงสร้างของกฎของคุณควรเป็นไปตามโครงสร้างของข้อมูลที่คุณจัดเก็บไว้ในฐานข้อมูลของคุณ ตัวอย่างเช่น ในแอปแชทที่มีรายการข้อความ คุณอาจมีข้อมูลที่มีลักษณะดังนี้:

  {
    "messages": {
      "message0": {
        "content": "Hello",
        "timestamp": 1405704370369
      },
      "message1": {
        "content": "Goodbye",
        "timestamp": 1405704395231
      },
      ...
    }
  }

กฎของคุณควรสะท้อนโครงสร้างนั้น ตัวอย่างเช่น:

  {
    "rules": {
      "messages": {
        "$message": {
          // only messages from the last ten minutes can be read
          ".read": "data.child('timestamp').val() > (now - 600000)",

          // new messages must have a string content and a number timestamp
          ".validate": "newData.hasChildren(['content', 'timestamp']) &&
                        newData.child('content').isString() &&
                        newData.child('timestamp').isNumber()"
        }
      }
    }
  }

ดังตัวอย่างข้างต้น กฎฐานข้อมูลเรียลไทม์สนับสนุนตัวแปร $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 }
      }
    }
  }

วิธี

ใน Realtime Database มีกฎสามประเภท กฎสองประเภทเหล่านี้ — read และ write — นำไปใช้กับวิธีการของคำขอที่เข้ามา ประเภทกฎ validate จะบังคับใช้โครงสร้างข้อมูลและตรวจสอบรูปแบบและเนื้อหาของข้อมูล กฎจะเรียกใช้ .validate หลังจากตรวจสอบว่ากฎ .write ให้สิทธิ์การเข้าถึง

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

ตามค่าเริ่มต้น หากไม่มีกฎอนุญาต การเข้าถึงเส้นทางจะถูกปฏิเสธ

สภาพอาคาร

คลาวด์ไฟร์สโตร์

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

ตัวแปร request

ตัวแปร request ประกอบด้วยฟิลด์ต่อไปนี้และข้อมูลที่เกี่ยวข้อง:

request.auth

JSON Web Token (JWT) ที่มีข้อมูลรับรองการตรวจสอบสิทธิ์จาก Firebase Authentication โทเค็น auth ประกอบด้วยชุดของการอ้างสิทธิ์แบบมาตรฐานและการอ้างสิทธิ์แบบกำหนดเองใดๆ ที่คุณสร้างผ่านการตรวจสอบสิทธิ์ Firebase เรียนรู้เพิ่มเติมเกี่ยวกับ กฎความปลอดภัยของ Firebase และการตรวจสอบสิทธิ์

request.method

request.method อาจเป็นวิธีการมาตรฐานหรือวิธีการที่กำหนดเองก็ได้ วิธีการอำนวยความสะดวก read และ write ยังมีอยู่เพื่อลดความซับซ้อนของกฎการเขียนที่ใช้กับวิธีมาตรฐานแบบอ่านอย่างเดียวหรือเขียนอย่างเดียวทั้งหมดตามลำดับ

request.params

request.params รวมข้อมูลใดๆ ที่ไม่เกี่ยวข้องโดยเฉพาะกับ request.resource ที่อาจเป็นประโยชน์สำหรับการประเมินผล ในทางปฏิบัติ แผนที่นี้ควรว่างเปล่าสำหรับวิธีมาตรฐานทั้งหมด และควรมีข้อมูลที่ไม่ใช่ทรัพยากรสำหรับวิธีการแบบกำหนดเอง บริการต้องระมัดระวังไม่เปลี่ยนชื่อหรือแก้ไขประเภทของคีย์และค่าใดๆ ที่แสดงเป็นพารามิเตอร์

request.path

request.path เป็นเส้นทางสำหรับ resource เป้าหมาย เส้นทางสัมพันธ์กับการบริการ ส่วนเส้นทางที่มีอักขระที่ไม่ใช่ URL ที่ปลอดภัย เช่น / ได้รับการเข้ารหัส URL

ตัวแปร resource

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

ตัวดำเนินการและลำดับความสำคัญของตัวดำเนินการ

ใช้ตารางด้านล่างเป็นข้อมูลอ้างอิงสำหรับโอเปอเรเตอร์และลำดับความสำคัญที่เกี่ยวข้องในกฎสำหรับ Cloud Firestore และ Cloud Storage

รับนิพจน์ตามอำเภอใจ a และ b ฟิลด์ f และดัชนี i

ผู้ดำเนินการ คำอธิบาย การเชื่อมโยง
a[i] a() af ดัชนี การโทร การเข้าถึงฟิลด์ จากซ้ายไปขวา
!a -a การปฏิเสธแบบเอกนารี จากขวาไปซ้าย
a/ba%ba*b ตัวดำเนินการคูณ จากซ้ายไปขวา
a+b ab ตัวดำเนินการเพิ่มเติม จากซ้ายไปขวา
a>ba>=ba ตัวดำเนินการเชิงสัมพันธ์ จากซ้ายไปขวา
a in b การมีอยู่ในรายการหรือแผนที่ จากซ้ายไปขวา
a is type การเปรียบเทียบประเภท โดยที่ type อาจเป็นบูล, int, ลอย, ตัวเลข, สตริง, รายการ, แผนที่, การประทับเวลา, ระยะเวลา, เส้นทาง หรือ latlng จากซ้ายไปขวา
a==ba!=b ตัวดำเนินการเปรียบเทียบ จากซ้ายไปขวา
a && b และแบบมีเงื่อนไข จากซ้ายไปขวา
a || b แบบมีเงื่อนไขหรือ จากซ้ายไปขวา
a ? true_value : false_value การแสดงออกแบบไตรภาค จากซ้ายไปขวา

การจัดเก็บเมฆ

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

ตัวแปร request

ตัวแปร request ประกอบด้วยฟิลด์ต่อไปนี้และข้อมูลที่เกี่ยวข้อง:

request.auth

JSON Web Token (JWT) ที่มีข้อมูลรับรองการตรวจสอบสิทธิ์จาก Firebase Authentication โทเค็น auth ประกอบด้วยชุดของการอ้างสิทธิ์แบบมาตรฐานและการอ้างสิทธิ์แบบกำหนดเองใดๆ ที่คุณสร้างผ่านการตรวจสอบสิทธิ์ Firebase เรียนรู้เพิ่มเติมเกี่ยวกับ กฎความปลอดภัยของ Firebase และการตรวจสอบสิทธิ์

request.method

request.method อาจเป็นวิธีการมาตรฐานหรือวิธีการที่กำหนดเองก็ได้ วิธีการอำนวยความสะดวก read และ write ยังมีอยู่เพื่อลดความซับซ้อนของกฎการเขียนที่ใช้กับวิธีมาตรฐานแบบอ่านอย่างเดียวหรือเขียนอย่างเดียวทั้งหมดตามลำดับ

request.params

request.params รวมข้อมูลใดๆ ที่ไม่เกี่ยวข้องโดยเฉพาะกับ request.resource ที่อาจเป็นประโยชน์สำหรับการประเมินผล ในทางปฏิบัติ แผนที่นี้ควรว่างเปล่าสำหรับวิธีมาตรฐานทั้งหมด และควรมีข้อมูลที่ไม่ใช่ทรัพยากรสำหรับวิธีการแบบกำหนดเอง บริการต้องระมัดระวังไม่เปลี่ยนชื่อหรือแก้ไขประเภทของคีย์และค่าใดๆ ที่แสดงเป็นพารามิเตอร์

request.path

request.path เป็นเส้นทางสำหรับ resource เป้าหมาย เส้นทางสัมพันธ์กับการบริการ ส่วนเส้นทางที่มีอักขระที่ไม่ใช่ URL ที่ปลอดภัย เช่น / ได้รับการเข้ารหัส URL

ตัวแปร resource

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

ตัวดำเนินการและลำดับความสำคัญของตัวดำเนินการ

ใช้ตารางด้านล่างเป็นข้อมูลอ้างอิงสำหรับโอเปอเรเตอร์และลำดับความสำคัญที่เกี่ยวข้องในกฎสำหรับ Cloud Firestore และ Cloud Storage

รับนิพจน์ตามอำเภอใจ a และ b ฟิลด์ f และดัชนี i

ผู้ดำเนินการ คำอธิบาย การเชื่อมโยง
a[i] a() af ดัชนี การโทร การเข้าถึงฟิลด์ จากซ้ายไปขวา
!a -a การปฏิเสธแบบเอกนารี จากขวาไปซ้าย
a/ba%ba*b ตัวดำเนินการคูณ จากซ้ายไปขวา
a+b ab ตัวดำเนินการเพิ่มเติม จากซ้ายไปขวา
a>ba>=ba ตัวดำเนินการเชิงสัมพันธ์ จากซ้ายไปขวา
a in b การมีอยู่ในรายการหรือแผนที่ จากซ้ายไปขวา
a is type การเปรียบเทียบประเภท โดยที่ type อาจเป็นบูล, int, ลอย, ตัวเลข, สตริง, รายการ, แผนที่, การประทับเวลา, ระยะเวลา, เส้นทาง หรือ latlng จากซ้ายไปขวา
a==ba!=b ตัวดำเนินการเปรียบเทียบ จากซ้ายไปขวา
a && b และแบบมีเงื่อนไข จากซ้ายไปขวา
a || b แบบมีเงื่อนไขหรือ จากซ้ายไปขวา
a ? true_value : false_value การแสดงออกแบบไตรภาค จากซ้ายไปขวา

ฐานข้อมูลเรียลไทม์

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

ตัวแปรที่กำหนดไว้ล่วงหน้า

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

ตัวแปรที่กำหนดไว้ล่วงหน้า
ตอนนี้ เวลาปัจจุบันเป็นมิลลิวินาทีนับตั้งแต่ยุค Linux วิธีนี้ใช้ได้ผลดีเป็นพิเศษในการตรวจสอบการประทับเวลาที่สร้างด้วย firebase.database.ServerValue.TIMESTAMP ของ SDK
ราก RuleDataSnapshot แสดงถึงเส้นทางรูทในฐานข้อมูล Firebase ตามที่มีอยู่ก่อนการดำเนินการที่พยายาม
ข้อมูลใหม่ RuleDataSnapshot ที่แสดงข้อมูลตามที่จะมีอยู่หลังจากการพยายามดำเนินการ รวมถึงข้อมูลใหม่ที่กำลังเขียนและข้อมูลที่มีอยู่
ข้อมูล RuleDataSnapshot ที่แสดงข้อมูลตามที่มีอยู่ก่อนการดำเนินการที่พยายาม
ตัวแปร $ เส้นทางไวด์การ์ดที่ใช้แทนรหัสและคีย์ลูกแบบไดนามิก
รับรองความถูกต้อง แสดงถึงเพย์โหลดโทเค็นของผู้ใช้ที่ได้รับการรับรองความถูกต้อง

ตัวแปรเหล่านี้ใช้ได้ทุกที่ในกฎของคุณ ตัวอย่างเช่น กฎความปลอดภัยด้านล่างช่วยให้แน่ใจว่าข้อมูลที่เขียนไปยังโหนด /foo/ ต้องเป็นสตริงที่มีความยาวน้อยกว่า 100 อักขระ:

{
  "rules": {
    "foo": {
      // /foo is readable by the world
      ".read": true,

      // /foo is writable by the world
      ".write": true,

      // data written to /foo must be a string less than 100 characters
      ".validate": "newData.isString() && newData.val().length < 100"
    }
  }
}

กฎที่ใช้ข้อมูล

ข้อมูลใดๆ ในฐานข้อมูลของคุณสามารถนำมาใช้ในกฎของคุณได้ การใช้ตัวแปรที่กำหนดไว้ล่วงหน้า root , data และ newData คุณสามารถเข้าถึงเส้นทางใดๆ ก็ได้ตามที่จะมีอยู่ก่อนหรือหลังเหตุการณ์การเขียน

ลองพิจารณาตัวอย่างนี้ ซึ่งอนุญาตให้ดำเนินการเขียนได้ตราบใดที่ค่าของโหนด /allow_writes/ เป็น true โหนดพาเรนต์ไม่มีชุดแฟล็ก readOnly และมีรายการย่อยชื่อ foo ในข้อมูลที่เขียนใหม่:

".write": "root.child('allow_writes').val() === true &&
          !data.parent().child('readOnly').exists() &&
          newData.child('foo').exists()"

กฎเกณฑ์การสืบค้น

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

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

"baskets": {
  ".read": "auth.uid !== null &&
            query.orderByChild === 'owner' &&
            query.equalTo === auth.uid" // restrict basket access to owner of basket
}

การสืบค้นต่อไปนี้ ซึ่งรวมถึงพารามิเตอร์การสืบค้นในกฎจะสำเร็จ:

db.ref("baskets").orderByChild("owner")
                 .equalTo(auth.currentUser.uid)
                 .on("value", cb)                 // Would succeed

อย่างไรก็ตาม แบบสอบถามที่ไม่มีพารามิเตอร์ในกฎจะล้มเหลว ด้วยข้อผิดพลาด PermissionDenied :

db.ref("baskets").on("value", cb)                 // Would fail with PermissionDenied

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

ตัวอย่างเช่น กฎต่อไปนี้จำกัดการเข้าถึงแบบอ่านเฉพาะผลลัพธ์ 1,000 รายการแรกของการสืบค้น โดยเรียงลำดับตามลำดับความสำคัญ:

messages: {
  ".read": "query.orderByKey &&
            query.limitToFirst <= 1000"
}

// Example queries:

db.ref("messages").on("value", cb)                // Would fail with PermissionDenied

db.ref("messages").limitToFirst(1000)
                  .on("value", cb)                // Would succeed (default order by key)

query. นิพจน์มีอยู่ในกฎความปลอดภัยของฐานข้อมูลเรียลไทม์

นิพจน์กฎที่ยึดตามแบบสอบถาม
การแสดงออก พิมพ์ คำอธิบาย
query.orderByKey
query.orderByPriority
query.orderByValue
บูลีน True สำหรับข้อความค้นหาที่เรียงลำดับตามคีย์ ลำดับความสำคัญ หรือค่า เท็จเป็นอย่างอื่น
query.orderByChild เชือก
โมฆะ
ใช้สตริงเพื่อแสดงเส้นทางสัมพัทธ์ไปยังโหนดลูก ตัวอย่างเช่น query.orderByChild === "address/zip" หากการสืบค้นไม่ได้รับคำสั่งจากโหนดย่อย ค่านี้จะเป็นโมฆะ
query.startAt
query.endAt
query.equalTo
เชือก
ตัวเลข
บูลีน
โมฆะ
ดึงขอบเขตของแบบสอบถามที่ดำเนินการ หรือส่งกลับค่า null หากไม่มีชุดที่ถูกผูกไว้
query.limitToFirst
query.limitToLast
ตัวเลข
โมฆะ
ดึงข้อมูลขีดจำกัดในการดำเนินการค้นหา หรือส่งกลับค่า null หากไม่มีการตั้งค่าขีดจำกัด

ผู้ประกอบการ

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

การสร้างเงื่อนไข

เงื่อนไขที่แท้จริงของคุณจะแตกต่างกันไปขึ้นอยู่กับการเข้าถึงที่คุณต้องการให้ กฎต่างๆ มีเจตนาให้ความยืดหยุ่นอย่างมาก ดังนั้นกฎของแอปของคุณจึงอาจเรียบง่ายหรือซับซ้อนได้ตามที่คุณต้องการในท้ายที่สุด

สำหรับคำแนะนำบางประการในการสร้างกฎที่เรียบง่ายและพร้อมใช้งาน โปรดดูที่ กฎความปลอดภัยขั้นพื้นฐาน