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

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

ไม่ว่าจะใช้เครื่องมือใดเพื่อเรียกใช้ API การจัดการจะทำสิ่งต่อไปนี้

  • นำเข้าแหล่งที่มาของกฎ: ชุดของกฎที่ปกติแล้วจะเป็นไฟล์โค้ดที่มีคำสั่งกฎการรักษาความปลอดภัยของ Firebase
  • จัดเก็บแหล่งที่มาที่นำเข้าเป็น ruleset ที่เปลี่ยนแปลงไม่ได้
  • ติดตามการติดตั้งใช้งานของชุดกฎแต่ละชุดในรุ่น บริการที่เปิดใช้กฎการรักษาความปลอดภัยของ 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

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

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

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

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

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

สำหรับกฎความปลอดภัยของ 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 และการทดสอบเชิงอรรถศาสตร์จะพร้อมใช้งานโดยใช้ Rules Playground

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

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

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

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

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

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

ใช้ Admin SDK

คุณใช้ Admin SDK สำหรับ rulesets ของ 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 ด้วย 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;
      }
    }

สำหรับการทำให้ใช้งานได้ขนาดใหญ่มากซึ่งถึงขีดจำกัด 2500 ชุดกฎเมื่อเวลาผ่านไป คุณสามารถสร้างตรรกะเพื่อลบกฎที่เก่าที่สุดในรอบเวลาคงที่ได้ เช่น หากต้องการลบชุดกฎทั้งหมดที่ทำให้ใช้งานได้นานกว่า 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 ใช้งานได้โดยใช้ API การจัดการ API การจัดการช่วยให้คุณมีความยืดหยุ่นมากที่สุด

และโปรดทราบข้อจํากัดต่อไปนี้

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

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

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

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

ขั้นตอนทั่วไปในการสร้างและทำให้ชุดกฎใช้งานได้โดยใช้ 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 สำหรับไฟล์นี้ จากนั้นคุณสามารถใช้แหล่งที่มาในไฟล์นี้เพื่อเติมข้อมูลเพย์โหลดที่จำเป็นในการสร้างชุดกฎด้วยการเรียก REST projects.rulesets.create ในที่นี้ ให้ใช้คำสั่ง 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 จะใช้เวลาหลายนาทีจึงจะเผยแพร่ได้อย่างสมบูรณ์ เมื่อใช้ REST API การจัดการเพื่อติดตั้งใช้งาน โปรดหลีกเลี่ยงเงื่อนไขการแข่งขันที่แอปอาศัยกฎที่การทำให้ใช้งานได้ยังไม่เสร็จสมบูรณ์ในทันที

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

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

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

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

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

สำหรับการทำให้ใช้งานได้ขนาดใหญ่มากซึ่งถึงขีดจำกัด 2500 ชุดกฎเมื่อเวลาผ่านไป คุณสามารถสร้างตรรกะเพื่อลบกฎที่เก่าที่สุดในรอบเวลาคงที่ได้ เช่น หากต้องการลบชุดกฎทั้งหมดที่ทำให้ใช้งานได้นานกว่า 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 เพื่อเปิดใช้สิทธิ์ในการเชื่อมต่อผลิตภัณฑ์ทั้งสอง

หากคุณตัดสินใจที่จะปิดใช้การรักษาความปลอดภัยแบบข้ามบริการดังกล่าว

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

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

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