จัดการและใช้งานกฎการรักษาความปลอดภัยของ Firebase

Firebase มีเครื่องมือมากมายให้คุณจัดการกฎ แต่ละเครื่องมือมีประโยชน์ในกรณีเฉพาะ และแต่ละอย่างใช้ API การจัดการกฎด้านความปลอดภัยของ Firebase แบ็กเอนด์เดียวกัน

ไม่ว่าจะใช้เครื่องมือใดในการเรียกใช้ Management API จะทําดังนี้

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

ใช้ Firebase CLI

Firebase CLI ช่วยให้คุณอัปโหลดแหล่งที่มาในเครื่องและทำให้รุ่นใช้งานได้ Firebase Local Emulator Suite ของ CLI ช่วยให้คุณทำการทดสอบแหล่งที่มาในเครื่องได้อย่างเต็มรูปแบบ

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

สร้างไฟล์การกำหนดค่า

เมื่อกำหนดค่าโปรเจ็กต์ Firebase โดยใช้ Firebase CLI คุณจะสร้างไฟล์การกำหนดค่า .rules ในไดเรกทอรีโปรเจ็กต์ได้ ใช้คำสั่งต่อไปนี้เพื่อเริ่มกำหนดค่าโปรเจ็กต์ Firebase

Cloud Firestore

// Set up Firestore in your project directory, creates a .rules file
firebase init firestore

Realtime Database

// Set up Realtime Database in your project directory, creates a .rules file
firebase init database

Cloud Storage

// Set up Storage in your project directory, creates a .rules file
firebase init storage

แก้ไขและอัปเดตกฎ

แก้ไขแหล่งที่มาของกฎโดยตรงในไฟล์การกำหนดค่า .rules

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

ทดสอบการอัปเดต

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

หากคุณทำงานกับ CLI ชุดเครื่องมือนี้จะเป็นเครื่องมือที่ยอดเยี่ยมสำหรับการทดสอบกฎการรักษาความปลอดภัยของ Firebase ใช้ชุดโปรแกรมจำลองในเครื่องเพื่อทดสอบการอัปเดตในเครื่อง และยืนยันว่ากฎของแอปแสดงลักษณะการทำงานที่คุณต้องการ

นำการอัปเดตไปใช้

เมื่อคุณอัปเดตและทดสอบกฎแล้ว ให้ทำให้แหล่งที่มาใช้งานได้จริง

สำหรับกฎความปลอดภัยของ Cloud Firestore ให้เชื่อมโยงไฟล์ .rules กับฐานข้อมูลที่มีชื่อเริ่มต้นและเพิ่มเติมโดยการตรวจสอบและอัปเดตไฟล์ firebase.json

ใช้คำสั่งต่อไปนี้เพื่อเลือกทำให้กฎใช้งานได้เพียงลำพัง หรือติดตั้งใช้งานกฎดังกล่าวโดยเป็นส่วนหนึ่งของกระบวนการติดตั้งใช้งานปกติ

Cloud Firestore

// Deploy rules for all databases configured in your firebase.json
firebase deploy --only firestore:rules
// Deploy rules for the specified database configured in your firebase.json firebase deploy --only firestore:<databaseId>

Realtime Database

// Deploy your .rules file
firebase deploy --only database

Cloud Storage

// Deploy your .rules file
firebase deploy --only storage

ใช้คอนโซล Firebase

นอกจากนี้ คุณยังแก้ไขแหล่งที่มาของกฎ และทำให้ใช้งานได้เป็นรุ่นจากคอนโซล Firebase ได้ด้วย การทดสอบแบบไวยากรณ์จะดำเนินการเมื่อคุณแก้ไข UI ของคอนโซล Firebase และการทดสอบเชิงความหมายพร้อมให้ใช้งานโดยใช้ฟีเจอร์กฎ Playground

แก้ไขและอัปเดตกฎ

  1. เปิดคอนโซล Firebase แล้วเลือกโปรเจ็กต์
  2. จากนั้นเลือก Realtime Database, Cloud Firestore หรือพื้นที่เก็บข้อมูลจากการนำทางของผลิตภัณฑ์ แล้วคลิกกฎเพื่อไปยังเครื่องมือแก้ไขกฎ
  3. แก้ไขกฎในเครื่องมือแก้ไขโดยตรง

ทดสอบการอัปเดต

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

นำการอัปเดตไปใช้

เมื่อพอใจกับการอัปเดตตามที่คาดหวังแล้ว ให้คลิกเผยแพร่

ใช้ Admin SDK

คุณใช้ Admin SDK สำหรับชุดกฎของ Node.js ได้ การเข้าถึงแบบเป็นโปรแกรมนี้ช่วยให้คุณทำสิ่งต่อไปนี้ได้

  • ใช้เครื่องมือที่กำหนดเอง สคริปต์ แดชบอร์ด และไปป์ไลน์ CI/CD เพื่อจัดการกฎ
  • จัดการกฎในโปรเจ็กต์ Firebase หลายโปรเจ็กต์ได้ง่ายขึ้น

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

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

โปรดศึกษาข้อจำกัดต่อไปนี้ด้วย

  • กฎต้องมีขนาดเล็กกว่า 256 KiB ของข้อความที่เข้ารหัส UTF-8 เมื่อทำให้เป็นอนุกรม
  • โปรเจ็กต์มีชุดกฎที่ทำให้ใช้งานได้ทั้งหมดได้สูงสุด 2,500 ชุด เมื่อถึงขีดจำกัดนี้แล้ว คุณต้องลบชุดกฎเก่าบางส่วนก่อนสร้างชุดกฎใหม่

สร้างและทำให้ชุดกฎ Cloud Storage หรือ Cloud Firestore ใช้งานได้

เวิร์กโฟลว์ทั่วไปในการจัดการกฎความปลอดภัยด้วย Admin SDK อาจมี 3 ขั้นตอนแยกกันดังนี้

  1. สร้างแหล่งที่มาของไฟล์กฎ (ไม่บังคับ)
  2. สร้างชุดกฎ
  3. เผยแพร่หรือปรับใช้ชุดกฎใหม่

SDK มีวิธีในการรวมขั้นตอนเหล่านี้ไว้ในการเรียก API เดียวสำหรับกฎความปลอดภัยของ Cloud Storage และ Cloud Firestore เช่น

    const source = `service cloud.firestore {
      match /databases/{database}/documents {
        match /carts/{cartID} {
          allow create: if request.auth != null && request.auth.uid == request.resource.data.ownerUID;
          allow read, update, delete: if request.auth != null && request.auth.uid == resource.data.ownerUID;
        }
      }
    }`;
    // Alternatively, load rules from a file
    // const fs = require('fs');
    // const source = fs.readFileSync('path/to/firestore.rules', 'utf8');

    await admin.securityRules().releaseFirestoreRulesetFromSource(source);

รูปแบบเดียวกันนี้ใช้ได้กับกฎ Cloud Storage ที่มี releaseFirestoreRulesetFromSource()

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

    const rf = admin.securityRules().createRulesFileFromSource('firestore.rules', source);
    const rs = await admin.securityRules().createRuleset(rf);
    await admin.securityRules().releaseFirestoreRuleset(rs);

อัปเดตชุดกฎของ Realtime Database

หากต้องการอัปเดตชุดกฎ Realtime Database ด้วย Admin SDK ให้ใช้เมธอด getRules() และ setRules() ของ admin.database คุณสามารถเรียกชุดกฎในรูปแบบ JSON หรือเป็นสตริงที่มีความคิดเห็นรวมอยู่ด้วย

วิธีอัปเดตชุดกฎ

    const source = `{
      "rules": {
        "scores": {
          ".indexOn": "score",
          "$uid": {
            ".read": "$uid == auth.uid",
            ".write": "$uid == auth.uid"
          }
        }
      }
    }`;
    await admin.database().setRules(source);

จัดการชุดกฎ

Admin SDK ให้คุณแสดงรายการกฎที่มีอยู่ทั้งหมดด้วย admin.securityRules().listRulesetMetadata เพื่อช่วยจัดการชุดกฎขนาดใหญ่ เช่น

    const allRulesets = [];
    let pageToken = null;
    while (true) {
      const result = await admin.securityRules().listRulesetMetadata(pageToken: pageToken);
      allRulesets.push(...result.rulesets);
      pageToken = result.nextPageToken;
      if (!pageToken) {
        break;
      }
    }

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

    const thirtyDays = new Date(Date.now() - THIRTY_DAYS_IN_MILLIS);
    const promises = [];
    allRulesets.forEach((rs) => {
      if (new Date(rs.createTime) < thirtyDays) {
        promises.push(admin.securityRules().deleteRuleset(rs.name));
      }
    });
    await Promise.all(promises);
    console.log(`Deleted ${promises.length} rulesets.`);

ใช้ REST API

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

โปรดศึกษาข้อจำกัดต่อไปนี้ด้วย

  • กฎต้องมีขนาดเล็กกว่า 256 KiB ของข้อความที่เข้ารหัส UTF-8 เมื่อทำให้เป็นอนุกรม
  • โปรเจ็กต์มีชุดกฎที่ทำให้ใช้งานได้ทั้งหมดได้สูงสุด 2,500 ชุด เมื่อถึงขีดจำกัดนี้แล้ว คุณต้องลบชุดกฎเก่าบางส่วนก่อนสร้างชุดกฎใหม่

สร้างและทำให้ชุดกฎ Cloud Firestore หรือ Cloud Storage ใช้งานได้ด้วย REST

ตัวอย่างในส่วนนี้ใช้กฎ Firestore แต่ก็อาจใช้กับกฎ Cloud Storage ได้เช่นกัน

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

ขั้นตอนทั่วไปสำหรับการสร้างและทำให้ชุดกฎใช้งานได้โดยใช้ API การจัดการมีดังนี้

  1. สร้างแหล่งที่มาของไฟล์กฎ
  2. สร้างชุดกฎ
  3. ปล่อย (ทำให้ใช้งานได้) ชุดกฎใหม่

สร้างแหล่งที่มา

สมมติว่าคุณกำลังสร้างโปรเจ็กต์ Firebase secure_commerce และต้องการทำให้กฎ Cloud Firestore ที่ล็อกไว้ใช้งานได้ในฐานข้อมูลในโปรเจ็กต์ชื่อ east_store

คุณสามารถนำกฎเหล่านี้ไปใช้ในไฟล์ firestore.rules

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if false;
    }
  }
}

สร้างชุดกฎ

จากนั้นให้สร้างลายนิ้วมือที่เข้ารหัสฐาน 64 สำหรับไฟล์นี้ จากนั้นคุณสามารถใช้แหล่งที่มาในไฟล์นี้เพื่อเติมข้อมูลเพย์โหลดที่จำเป็นในการสร้างชุดกฎที่มีการเรียก projects.rulesets.create REST ตรงนี้ ให้ใช้คำสั่ง cat เพื่อแทรกเนื้อหาของ firestore.rules ลงในเพย์โหลด REST

สำหรับการติดตาม หากต้องการเชื่อมโยงรายการนี้กับฐานข้อมูล east_store ให้ตั้งค่า attachment_point เป็น east_store

curl -X POST -d '{
  "source": {
    "files": [
      {
        "content": "' $(cat storage.rules) '",
        "name": "firestore.rules",
        "fingerprint": <sha fingerprint>
      },
    "attachment_point": "firestore.googleapis.com/databases/east_store"
    ]
  }
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/rulesets'

API จะแสดงผลการตอบกลับการตรวจสอบและชื่อชุดกฎ เช่น projects/secure_commerce/rulesets/uuid123

เผยแพร่ชุดกฎ (ทำให้ใช้งานได้)

หากชุดกฎถูกต้อง ขั้นตอนสุดท้ายคือการทำให้ชุดกฎใหม่ใช้งานได้ในรุ่นที่มีชื่อ

curl -X POST -d '{
  "name": "projects/secure_commerce/releases/cloud.firestore/east_store"  ,
  "rulesetName": "projects/secure_commerce/rulesets/uuid123"
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/releases'

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

อัปเดตชุดกฎ Realtime Database ด้วย REST

Realtime Database มีอินเทอร์เฟซ REST ของตนเองสำหรับจัดการกฎ โปรดดูการจัดการกฎฐานข้อมูลเรียลไทม์ของ Firebase ผ่าน REST

จัดการชุดกฎด้วย REST

นอกจากเมธอด REST สำหรับสร้างชุดกฎและรุ่นต่างๆ แล้ว API การจัดการยังมีเมธอดเพื่อช่วยจัดการการทำให้ใช้งานได้ของกฎขนาดใหญ่ ดังนี้

  • แสดงรายการ รับ และลบชุดกฎ
  • แสดงรายการ รับ และลบกฎรุ่น

สำหรับการทำให้ใช้งานได้จำนวนมากที่ถึงขีดจำกัดของชุดกฎ 2, 500 รายการในช่วงเวลาหนึ่ง คุณสามารถสร้างตรรกะเพื่อลบกฎที่เก่าที่สุดในวงจรที่กำหนดไว้ได้ เช่น หากต้องการลบชุดกฎทั้งหมดที่ทำให้ใช้งานได้นานกว่า 30 วัน ให้เรียกใช้เมธอด projects.rulesets.list แยกวิเคราะห์รายการ JSON ของออบเจ็กต์ Ruleset ในคีย์ createTime จากนั้นเรียกใช้ project.rulesets.delete ในชุดกฎที่เกี่ยวข้องภายในวันที่ ruleset_id

ทดสอบการอัปเดตด้วย REST

สุดท้ายนี้ API การจัดการจะช่วยให้คุณทำการทดสอบเชิงไวยากรณ์และความหมายบนทรัพยากร Cloud Firestore และ Cloud Storage ในโปรเจ็กต์ที่ใช้งานจริงได้

การทดสอบด้วยคอมโพเนนต์ของ API นี้ประกอบไปด้วย

  1. การกำหนดออบเจ็กต์ JSON สำหรับ TestSuite เพื่อแสดงถึงชุดของออบเจ็กต์ TestCase
  2. กำลังส่ง TestSuite
  3. กำลังแยกวิเคราะห์ออบเจ็กต์ TestResult รายการ

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

 {
  "source":
  {
    "files":
    [
      {
        "name": "firestore.rules",
        "content": "service cloud.firestore {
          match /databases/{database}/documents {
            match /users/{userId}{
              allow read: if (request.auth.uid == userId);
            }
            function doc(subpath) {
              return get(/databases/$(database)/documents/$(subpath)).data;
            }
            function isAccountOwner(accountId) {
              return request.auth.uid == accountId 
                  || doc(/users/$(request.auth.uid)).accountId == accountId;
            }
            match /licenses/{accountId} {
              allow read: if isAccountOwner(accountId);
            }
          }
        }"
      }
    ]
  },
  "testSuite":
  {
    "testCases":
    [
      {
        "expectation": "ALLOW",
        "request": {
           "auth": {"uid": "123"},
           "path": "/databases/(default)/documents/licenses/abcd",
           "method": "get"},
        "functionMocks": [
            {
            "function": "get",
            "args": [{"exact_value": "/databases/(default)/documents/users/123"}],
            "result": {"value": {"data": {"accountId": "abcd"}}}
            }
          ]
      }
    ]
  }
}

จากนั้นเราจะส่ง TestSuite นี้มาประเมินด้วยเมธอด projects.test

curl -X POST -d '{
    ' $(cat testcase.json) '
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/rulesets/uuid123:test'

TestReport ที่แสดงผล (มีสถานะการทดสอบสำเร็จ/ล้มเหลว รายการข้อความแก้ไขข้อบกพร่อง รายการนิพจน์กฎที่เข้าชม และรายงานการประเมิน) จะยืนยันด้วยสถานะ "สำเร็จ" ว่าระบบอนุญาตให้เข้าถึงอย่างถูกต้อง

จัดการสิทธิ์สำหรับกฎความปลอดภัยของ Cloud Storage แบบข้ามบริการ

หากสร้างกฎความปลอดภัยของ Cloud Storage ที่ใช้เนื้อหาเอกสารใน Cloud Firestore เพื่อประเมินเงื่อนไขด้านความปลอดภัย คุณจะได้รับข้อความแจ้งในคอนโซล Firebase หรือ Firebase CLI ให้เปิดใช้สิทธิ์ในการเชื่อมต่อทั้ง 2 ผลิตภัณฑ์

หากคุณเลือกปิดใช้การรักษาความปลอดภัยข้ามบริการ จะมีผลดังนี้

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

  2. ใช้หน้า IAM ใน Google Cloud Console เพื่อลบบทบาท "Agent บริการ Firestore ของกฎ Firebase" โดยทำตามคำแนะนำสำหรับระบบคลาวด์สำหรับการเพิกถอนบทบาท

คุณจะได้รับแจ้งให้เปิดใช้ฟีเจอร์อีกครั้งในครั้งถัดไปที่บันทึกกฎข้ามบริการจาก Firebase CLI หรือคอนโซล Firebase