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

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

ไม่ว่าเครื่องมือใดก็ตามที่ใช้เรียกใช้ 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 โดยตรง

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

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

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

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

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

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

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

ใช้คำสั่งต่อไปนี้เพื่อทำให้ 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

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

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

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

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

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

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

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

ใช้ Admin SDK

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

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

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

อีกสิ่งสําคัญที่ควรทราบคือรุ่น Firebase Security Rules จะใช้เวลาหลายนาทีในการนำไปใช้งานอย่างเต็มรูปแบบ เมื่อใช้ Admin SDK เพื่อทําให้กฎมีผล โปรดหลีกเลี่ยงเงื่อนไขการแข่งขันซึ่งแอปของคุณใช้กฎที่การทําให้มีผลยังไม่เสร็จสมบูรณ์ในทันที หาก Use Case ของคุณกำหนดให้ต้องอัปเดตกฎการควบคุมการเข้าถึงเป็นประจำ ให้พิจารณาใช้โซลูชันที่ใช้ 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 Rules แต่จะใช้กับ Cloud Storage Rules ได้ด้วย

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

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

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

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

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

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

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

สร้างชุดกฎ

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

สําหรับการติดตาม ให้ตั้งค่า attachment_point เป็น east_store เพื่อเชื่อมโยงกับฐานข้อมูล 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 ของตนเองสำหรับการจัดการ Rules ดูหัวข้อการจัดการ Firebase Realtime Database Rules ผ่าน REST

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

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

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

สําหรับการติดตั้งใช้งานขนาดใหญ่มากที่ถึงขีดจํากัดของชุดกฎ 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 ในตัวอย่างนี้ เราจะส่งRulesแหล่งที่มาของภาษาในบรรทัดเดียวกับเพย์โหลด REST พร้อมกับชุดทดสอบเพื่อเรียกใช้กฎเหล่านั้น เราระบุความคาดหวังในการประเมินกฎและคำขอของลูกค้าที่จะทดสอบชุดกฎ นอกจากนี้ คุณยังระบุความสมบูรณ์ของรายงานการทดสอบได้ด้วย โดยการใช้ค่า "FULL" เพื่อระบุว่าควรรวมผลลัพธ์สำหรับนิพจน์ภาษา 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 ที่แสดงผล (ซึ่งมีสถานะการทดสอบ "สําเร็จ/ไม่สําเร็จ" รายการข้อความแก้ไขข้อบกพร่อง รายการนิพจน์กฎที่เข้าชม และรายงานการประเมิน) จะยืนยันด้วยสถานะ "สําเร็จ" ว่ามีการอนุญาตการเข้าถึงอย่างเหมาะสม

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

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

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

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

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

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