Join us in person and online for Firebase Summit on October 18, 2022. Learn how Firebase can help you accelerate app development, release your app with confidence, and scale with ease. Register now

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

จัดทุกอย่างให้เป็นระเบียบอยู่เสมอด้วยคอลเล็กชัน บันทึกและจัดหมวดหมู่เนื้อหาตามค่ากำหนดของคุณ

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

ไม่ว่าจะใช้เครื่องมือใดในการเรียกใช้ 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 Security Rules ใช้ Local Emulator Suite เพื่อทดสอบการอัปเดตในเครื่องและยืนยันว่ากฎของแอปแสดงพฤติกรรมที่คุณต้องการ

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

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

Cloud Firestore

// Deploy your .rules file
firebase deploy --only firestore:rules

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

// 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 ในตัวแก้ไขกฎ แก้ไขการตั้งค่า แล้วคลิก เรียกใช้ มองหาข้อความยืนยันที่ด้านบนของตัวแก้ไข

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

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

ใช้ Admin SDK

คุณสามารถใช้ Admin SDK สำหรับ Node.js ruleset ด้วยการเข้าถึงแบบเป็นโปรแกรม คุณสามารถ:

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

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

สิ่งสำคัญอีกประการที่ควรทราบคือการเผยแพร่กฎความปลอดภัยของ Firebase จะใช้เวลาหลายนาทีในการเผยแพร่อย่างสมบูรณ์ เมื่อใช้ Admin SDK ในการปรับใช้กฎ ตรวจสอบให้แน่ใจว่าได้หลีกเลี่ยงสภาวะการแข่งขันที่แอปของคุณต้องอาศัยกฎที่การทำให้ใช้งานได้ยังไม่เสร็จสมบูรณ์ในทันที หากกรณีการใช้งานของคุณต้องมีการอัปเดตกฎการควบคุมการเข้าถึงบ่อยครั้ง ให้พิจารณาโซลูชันโดยใช้ Cloud Firestore ซึ่งออกแบบมาเพื่อลดสภาวะการแข่งขันแม้ว่าจะมีการอัปเดตบ่อยครั้ง

โปรดทราบข้อจำกัดเหล่านี้ด้วย:

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

สร้างและปรับใช้ชุดกฎ 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;
      }
    }

สำหรับการปรับใช้ที่มีขนาดใหญ่มากซึ่งถึงขีดจำกัดชุดกฎ 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 โดยใช้ API การจัดการ API การจัดการให้ความยืดหยุ่นสูงสุดแก่คุณ

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

โปรดทราบข้อจำกัดเหล่านี้ด้วย:

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

สร้างและปรับใช้ชุดกฎ Cloud Storage หรือ Cloud Firestore ด้วย REST

ตัวอย่างในส่วนนี้ใช้กฎของพื้นที่เก็บข้อมูล แม้ว่าจะนำไปใช้กับกฎของ Cloud Firestore ก็ตาม

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

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

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

สมมติว่าคุณกำลังทำงานใน secure_commerce Firebase และต้องการปรับใช้กฎ Cloud Storage ที่ล็อกไว้ คุณสามารถใช้กฎเหล่านี้ในไฟล์ storage.rules

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if false;
    }
  }
}

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

curl -X POST -d '{
  "source": {
    {
      "files": [
        {
          "content": "' $(cat storage.rules) '",
          "name": "storage.rules",
          "fingerprint": <sha fingerprint>
        }
      ]
    }
  }
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/rulesets'

API ส่งคืนการตอบกลับการตรวจสอบความถูกต้องและชื่อชุดกฎ เช่น projects/secure_commerce/rulesets/uuid123 หากชุดกฎถูกต้อง ขั้นตอนสุดท้ายคือการปรับใช้ชุดกฎใหม่ในรุ่นที่มีชื่อ

curl -X POST -d '{
  "name": "projects/secure_commerce/releases/prod/v23   "  ,
  "rulesetName": "projects/secure_commerce/rulesets/uuid123",
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/releases'

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

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

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

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

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

สำหรับการปรับใช้ที่มีขนาดใหญ่มากซึ่งถึงขีดจำกัดชุดกฎ 2500 เมื่อเวลาผ่านไป คุณสามารถสร้างตรรกะเพื่อลบกฎที่เก่าที่สุดในรอบเวลาที่คงที่ได้ ตัวอย่างเช่น หากต้องการลบชุดกฎ ทั้งหมด ที่ปรับใช้นานกว่า 30 วัน คุณสามารถเรียกใช้เมธอด project.ruleset.list แยกวิเคราะห์รายการ JSON ของออบ projects.rulesets.list กต์ 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 ควบคู่ไปกับชุดทดสอบเพื่อรันบนกฎเหล่านั้น เราระบุความคาดหวังในการประเมินกฎ และคำขอของลูกค้าที่จะทดสอบชุดกฎ คุณยังสามารถระบุความสมบูรณ์ของรายงานการทดสอบได้โดยใช้ค่า "เต็ม" เพื่อระบุผลลัพธ์สำหรับนิพจน์ภาษาของกฎทั้งหมดที่ควรรวมอยู่ในรายงาน รวมถึงนิพจน์ที่ไม่ตรงกับคำขอ

 {
  "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 ที่อนุญาตให้เข้าถึงได้อย่างเหมาะสม