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

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

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

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

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

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

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

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

ติดตั้งใช้งานการอัปเดต

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

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

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

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

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

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

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

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

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

ติดตั้งใช้งานการอัปเดต

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

ใช้ Admin SDK

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

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

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

สิ่งสำคัญอีกอย่างที่ควรทราบคือรุ่น Firebase Security Rules จะใช้เวลาหลายนาทีในการเผยแพร่อย่างสมบูรณ์ เมื่อใช้ 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 Security Rules สำหรับฐานข้อมูล Cloud Firestore หลายรายการในโปรเจ็กต์ แต่คุณอาจต้องการจัดการและติดตั้งใช้งาน Firebase Security Rules โดยใช้ Management API เอง Management API ช่วยให้คุณมีความยืดหยุ่นมากที่สุด

นอกจากนี้ โปรดทราบถึงขีดจำกัดต่อไปนี้

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

สร้างและติดตั้งใช้งานกฎ Cloud Firestore หรือ Cloud Storage ด้วย REST

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

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

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

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

สร้างแหล่งข้อมูล

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

คุณใช้กฎเหล่านี้ได้ในไฟล์ firestore.rules

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

สร้างชุดกฎ

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

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

Realtime Database มีอินเทอร์เฟซ REST ของตัวเองสำหรับจัดการ Security Rules ดูการจัดการ Realtime Database Security Rules ของ Firebase ผ่าน REST

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

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

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

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

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

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

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

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

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

 {
  "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 ที่แสดงผล (ซึ่งมีสถานะ SUCCESS/FAILURE ของการทดสอบ รายการข้อความแก้ไขข้อบกพร่อง รายการนิพจน์ของกฎที่เข้าชม และรายงานการประเมิน) จะยืนยันด้วยสถานะ SUCCESS ว่ามีการอนุญาตให้เข้าถึงอย่างถูกต้อง

จัดการสิทธิ์สำหรับ Cloud Storage Security Rules ข้ามบริการ

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

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

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

  2. ใช้หน้า IAM ในคอนโซล Google Cloud เพื่อลบบทบาท "Firebase Rules Firestore Service Agent" โดยทำตามคู่มือ Cloud สำหรับการเพิกถอนบทบาท

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