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

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

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

หากคุณใช้ CLI, Suite เป็นเครื่องมือที่ยอดเยี่ยมสำหรับ 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ได้ด้วย ระบบจะทำการ ทดสอบทางไวยากรณ์ขณะที่คุณแก้ไขใน Firebase UI ของคอนโซล และการทดสอบความหมายจะพร้อมใช้งานโดยใช้ Security Rules Playground

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

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

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

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

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

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

ใช้ 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 โดยใช้ API การจัดการเอง API การจัดการให้ความยืดหยุ่นสูงสุด

โปรดทราบขีดจำกัดต่อไปนี้ด้วย

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

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

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

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

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

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

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

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

หากต้องการติดตาม ให้ตั้งค่า 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 ของตัวเองสำหรับการจัดการ Security Rules ดู การจัดการ Firebase Realtime Database Security Rules ผ่าน REST

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

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

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

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

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

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

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

  1. กำหนดออบเจ็กต์ TestSuite JSON เพื่อแสดงชุดออบเจ็กต์ 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 เพื่อลบบทบาท "Agent บริการกฎของ Firebase สำหรับ Firestore" โดยทำตามคำแนะนำของ Cloud ในการ เพิกถอนบทบาท

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