Join us for Firebase Summit on November 10, 2021. Tune in to learn how Firebase can help you accelerate app development, release with confidence, and scale with ease. Register

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

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

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

  • ingests แหล่งกฎ: ชุดของกฎที่โดยปกติจะเป็นไฟล์โค้ดที่มีการรักษาความปลอดภัยงบ Firebase กฎ
  • ร้านติดเครื่องแหล่งที่มาเป็น ruleset ไม่เปลี่ยนรูป
  • แทร็คการใช้งานของแต่ละ ruleset ในรุ่น บริการที่เปิดใช้กฎความปลอดภัยของ Firebase จะค้นหารุ่นของโปรเจ็กต์เพื่อประเมินคำขอแต่ละรายการสำหรับทรัพยากรที่ปลอดภัย
  • ให้ความสามารถในการเรียกใช้การทดสอบประโยคและความหมายของ ruleset

ใช้ Firebase CLI

ด้วย Firebase CLI คุณสามารถอัปโหลดแหล่งท้องถิ่นและเผยแพร่การปรับใช้ CLI ของ Firebase ท้องถิ่น Emulator สวีทช่วยให้คุณสามารถดำเนินการทดสอบในท้องถิ่นเต็มรูปแบบของแหล่งที่มา

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

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

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

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 ทดสอบวากยสัมพันธ์จะดำเนินการตามที่คุณแก้ไขใน Firebase UI คอนโซลและการทดสอบ symantic สามารถใช้ได้โดยใช้กฎสนามเด็กเล่น

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

  1. เปิด คอนโซล Firebase และเลือกโครงการของคุณ
  2. จากนั้นเลือกฐานข้อมูลเรียลไทม์เมฆ FireStore หรือการจัดเก็บจากการนำสินค้าแล้วคลิกกฎเพื่อนำทางไปยังแก้ไขกฎ
  3. แก้ไขกฎของคุณโดยตรงในตัวแก้ไข

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

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

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

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

ใช้ Admin SDK

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

  • ใช้เครื่องมือแบบกำหนดเอง สคริปต์ แดชบอร์ด และไปป์ไลน์ 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);

รูปแบบเดียวกันนี้ทำงานสำหรับกฎการจัดเก็บเมฆกับ releaseFirestoreRulesetFromSource()

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

    const rf = admin.securityRules().createRulesFileFromSource('firestore.rules', source);
    const rs = await admin.securityRules().createRuleset(rf);
    await admin.securityRules().releaseFirestoreRuleset(rs);

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

การอัปเดตเรียลไทม์ rulesets ฐานข้อมูลด้วย 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);

จัดการชุดกฎ

เพื่อช่วยจัดการ rulesets ขนาดใหญ่ 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 เมื่อเวลาผ่านไป คุณสามารถสร้างตรรกะเพื่อลบกฎที่เก่าที่สุดในรอบเวลาที่คงที่ได้ ตัวอย่างเช่นในการลบ rulesets ทั้งหมดนำไปใช้งานได้นานกว่า 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 และต้องการที่จะปรับใช้ล็อคลงเมฆกฎการเก็บรักษา คุณสามารถใช้กฎเหล่านี้ใน storage.rules ไฟล์

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

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

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 ที่ส่งกลับตอบสนองต่อการตรวจสอบและชื่อ ruleset เช่น 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 การจัดการยังมีวิธีการเพื่อ:

  • รายการรับและ rulesets ลบ
  • รายการรับและกฎลบเผยแพร่

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

curl -X POST -d '{
    ' $(cat testcase.json) '
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/rulesets/uuid123:test'

กลับ TestReport (ที่มีการทดสอบความสำเร็จ / ล้มเหลวสถานะรายการของข้อความแก้ปัญหารายชื่อของการแสดงออกกฎเยี่ยมชมและรายงานการประเมินผลของพวกเขา) จะยืนยันกับความสำเร็จสถานะว่าการเข้าถึงที่ได้รับอนุญาตอย่างถูกต้อง