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

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

ไม่ว่าจะใช้เครื่องมือใดในการเรียกใช้ 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

ฐานข้อมูลเรียลไทม์

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

การจัดเก็บเมฆ

// 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 ใช้ 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>

ฐานข้อมูลเรียลไทม์

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

การจัดเก็บเมฆ

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

ใช้คอนโซล Firebase

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

แก้ไขและปรับปรุงกฎของคุณ

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

ทดสอบการอัปเดตของคุณ

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

ปรับใช้การอัปเดตของคุณ

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

ใช้ 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 อาจมีสามขั้นตอนแยกกัน:

  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);

อัปเดตชุดกฎฐานข้อมูลเรียลไทม์

หากต้องการอัปเดตชุดกฎฐานข้อมูลเรียลไทม์ด้วย 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 แม้ว่าจะใช้กฎของ Cloud Storage เช่นกัน

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

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

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

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

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

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

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

สร้างชุดกฎ

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

อัปเดตชุดกฎฐานข้อมูลเรียลไทม์ด้วย REST

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

จัดการสิทธิ์สำหรับกฎความปลอดภัยที่เก็บข้อมูลบนคลาวด์ข้ามบริการ

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

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

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

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

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