เรียนรู้ไวยากรณ์หลักของภาษาของกฎการรักษาความปลอดภัยของ Firebase สำหรับ Cloud Storage

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

คู่มือนี้จะอธิบายไวยากรณ์และโครงสร้างพื้นฐานของ Cloud Storage Security Rules เพื่อ สร้างชุดกฎที่สมบูรณ์

การประกาศบริการและฐานข้อมูล

Firebase Security Rules สำหรับ Cloud Storage เริ่มต้นด้วยการประกาศต่อไปนี้เสมอ

service firebase.storage {
    // ...
}

การประกาศ service firebase.storage จะกำหนดกฎไว้ที่ Cloud Storage ป้องกันความขัดแย้งระหว่าง Cloud Storage Security Rules กับ สำหรับผลิตภัณฑ์อื่นๆ เช่น Cloud Firestore

กฎการอ่าน/เขียนพื้นฐาน

กฎพื้นฐานประกอบด้วยคำสั่ง match ที่ระบุว่า Cloud Storage ที่เก็บข้อมูล คำสั่งจับคู่ที่ระบุชื่อไฟล์ และนิพจน์ allow ให้รายละเอียดเมื่ออ่านข้อมูลที่ระบุ allow นิพจน์ ระบุวิธีการเข้าถึง (เช่น อ่าน เขียน) และเงื่อนไข ภายใต้ที่อนุญาตหรือปฏิเสธการเข้าถึง

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

service firebase.storage {
  // The {bucket} wildcard indicates we match files in all Cloud Storage buckets
  match /b/{bucket}/o {
    // Match filename
    match /filename {
      allow read: if <condition>;
      allow write: if <condition>;
    }
  }
}

ข้อความที่ตรงกันทั้งหมดจะชี้ไปที่ไฟล์ ข้อความจับคู่สามารถชี้ไปยัง เช่นเดียวกับ match /images/profilePhoto.png

จับคู่ไวลด์การ์ด

นอกจากการชี้ไปยังไฟล์เดียวแล้ว Rules ยังใช้ไวลด์การ์ดได้ด้วย เพื่อชี้ไปยังไฟล์ที่มีคำนำหน้าสตริงที่กำหนดอยู่ในชื่อ รวมถึงเครื่องหมายทับ เช่น match /images/{imageId}

ในตัวอย่างด้านบน คำสั่งจับคู่จะใช้ไวยากรณ์ไวลด์การ์ด {imageId} ซึ่งหมายความว่ากฎนี้จะมีผลกับไฟล์ที่มี /images/ อยู่ขึ้นต้นชื่อ เช่น /images/profilePhoto.png หรือ /images/croppedProfilePhoto.png เมื่อ ระบบประเมินนิพจน์ allow ในคำสั่งการจับคู่ ตัวแปร imageId จะเปลี่ยนเป็นชื่อไฟล์ของรูปภาพ เช่น profilePhoto.png หรือ croppedProfilePhoto.png

อ้างอิงตัวแปรไวลด์การ์ดจากภายใน match เพื่อระบุไฟล์ได้ ชื่อหรือเส้นทางการให้สิทธิ์:

// Another way to restrict the name of a file
match /images/{imageId} {
  allow read: if imageId == "profilePhoto.png";
}

ข้อมูลตามลําดับชั้น

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

ลองพิจารณาสถานการณ์ของชุดไฟล์ที่มีชื่อขึ้นต้นด้วย ก้าน /images/ Firebase Security Rules จะใช้เฉพาะที่ชื่อไฟล์ที่ตรงกันเท่านั้น ดังนั้นสิทธิ์เข้าถึง การควบคุมที่กำหนดไว้ในชุด /images/ จะไม่มีผลกับชุดคำสั่ง /mp3s/ แต่ให้เขียนกฎที่ชัดเจนที่ตรงกับรูปแบบชื่อไฟล์ต่างกันแทน ดังนี้

service firebase.storage {
  match /b/{bucket}/o {
    match /images/{imageId} {
      allow read, write: if <condition>;
    }

    // Explicitly define rules for the 'mp3s' pattern
    match /mp3s/{mp3Id} {
      allow read, write: if <condition>;
    }
  }
}

เมื่อซ้อนคำสั่ง match เส้นทางของคำสั่ง match ด้านในคือ จะต่อท้ายเส้นทางของคำสั่ง match ด้านนอกเสมอ ดังต่อไปนี้ ชุดกฎสองชุดจึงมีความสำคัญเท่ากัน:

service firebase.storage {
  match /b/{bucket}/o {
    match /images {
      // Exact match for "images/profilePhoto.png"
      match /profilePhoto.png {
        allow write: if <condition>;
      }
    }
  }
}
service firebase.storage {
  match /b/{bucket}/o {
    // Exact match for "images/profilePhoto.png"
    match /images/profilePhoto.png {
      allow write: if <condition>;
      }
  }
}

ไวลด์การ์ดการจับคู่ที่เกิดซ้ำ

นอกจากไวลด์การ์ดที่ตรงกันและแสดงผลสตริงที่ส่วนท้ายของชื่อไฟล์แล้ว สามารถประกาศไวลด์การ์ดของกลุ่มหลายกลุ่มสำหรับการจับคู่ที่ซับซ้อนขึ้นได้โดย การเพิ่ม =** ในชื่อไวลด์การ์ด เช่น {path=**}:

// Partial match for files that start with "images"
match /images {

  // Exact match for "images/**"
  // e.g. images/users/user:12345/profilePhoto.png is matched
  // images/profilePhoto.png is also matched!
  match /{allImages=**} {
    // This rule matches one or more path segments (**)
    // allImages is a path that contains all segments matched
    allow read: if <other_condition>;
  }
}

หากมีกฎหลายข้อตรงกับไฟล์ ผลลัพธ์จะเป็น OR ของผลลัพธ์ทั้งหมด และการประเมินกฎ กล่าวคือ หากกฎใดตรงกับไฟล์ประเมินผลเป็น true ผลลัพธ์คือ true

ในกฎข้างต้น ไฟล์ "images/profilePhoto.png" สามารถอ่านได้ในกรณีต่อไปนี้ condition หรือ other_condition ประเมินค่าเป็น "จริง" ขณะที่ไฟล์ "images/users/user:12345/profilePhoto.png" จะขึ้นอยู่กับผลลัพธ์ของ other_condition

Cloud Storage Security Rules ไม่ต่อเนื่อง และจะมีการประเมินกฎเฉพาะเมื่อ เส้นทางคำขอตรงกับเส้นทางที่มีกฎที่ระบุ

เวอร์ชัน 1

Firebase Security Rules จะใช้เวอร์ชัน 1 โดยค่าเริ่มต้น ในเวอร์ชัน 1 ใช้ไวลด์การ์ดซ้ำ ตรงกับองค์ประกอบชื่อไฟล์อย่างน้อย 1 รายการ ไม่ใช่ 0 หรือมีองค์ประกอบมากกว่า 1 รายการ ดังนั้น match /images/{filenamePrefixWildcard}/{imageFilename=**} ตรงกับชื่อไฟล์ เช่น /images/profilePics/profile.png แต่ไม่ใช่ /images/badge.png ใช้ /images/{imagePrefixorFilename=**} แทน

ไวลด์การ์ดที่เกิดซ้ำต้องอยู่ท้ายคำสั่งการจับคู่

เราขอแนะนำให้ใช้เวอร์ชัน 2 หากต้องการฟีเจอร์ที่มีประสิทธิภาพมากขึ้น

เวอร์ชัน 2

ในเวอร์ชัน 2 ของ Firebase Security Rules ไวลด์การ์ดที่เกิดซ้ำจะจับคู่กับเส้นทาง 0 รายการขึ้นไป รายการ ดังนั้น การแข่งขัน /images/{filenamePrefixWildcard}/{imageFilename=**} รายการ ชื่อไฟล์ /images/profilePics/profile.png และ /images/badge.png

คุณต้องเลือกใช้เวอร์ชัน 2 โดยเพิ่ม rules_version = '2'; ที่ด้านบนสุดของ กฎความปลอดภัยของคุณ:

rules_version = '2';
service cloud.storage {
  match /b/{bucket}/o {
   ...
 }
}

คุณสามารถมีไวลด์การ์ดซ้ำได้สูงสุด 1 รายการต่อคำสั่งจับคู่ แต่ เวอร์ชัน 2 คุณสามารถวางไวลด์การ์ดนี้ไว้ที่ใดก็ได้ในคำสั่งการจับคู่ สำหรับ ตัวอย่าง:

rules_version = '2';
service firebase.storage {
 match /b/{bucket}/o {
   // Matches any file in a songs "subdirectory" under the
   // top level of your Cloud Storage bucket.
   match /{prefixSegment=**}/songs/{mp3filenames} {
     allow read, write: if <condition>;
   }
  }
}

การดำเนินการแบบละเอียด

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

แบ่งการดำเนินการ read ออกเป็น get และ list ได้

มีกฎ write รายการได้ ออกเป็น create, update และ delete:

service firebase.storage {
  match /b/{bucket}/o {
    // A read rule can be divided into read and list rules
    match /images/{imageId} {
      // Applies to single file read requests
      allow get: if <condition>;
      // Applies to list and listAll requests (Rules Version 2)
      allow list: if <condition>;

    // A write rule can be divided into create, update, and delete rules
    match /images/{imageId} {
      // Applies to writes to file contents
      allow create: if <condition>;

      // Applies to updates to (pre-existing) file metadata
      allow update: if <condition>;

      // Applies to delete operations
      allow delete: if <condition>;
    }
  }
 }
}

ข้อความการจับคู่ที่ทับซ้อนกัน

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

service firebase.storage {
  match b/{bucket}/o {
    // Matches file names directly inside of '/images/'.
    match /images/{imageId} {
      allow read, write: if false;
    }

    // Matches file names anywhere under `/images/`
    match /images/{imageId=**} {
      allow read, write: if true;
    }
  }
}

ในตัวอย่างข้างต้น การอ่านและเขียนทั้งหมดไปยังไฟล์ที่มีชื่อขึ้นต้นด้วย อนุญาตให้ใช้/images/ได้ เนื่องจากกฎข้อที่ 2 จะเป็น true เสมอ แม้ว่า กฎแรกคือ false

กฎไม่ใช่ตัวกรอง

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

ตัวอย่างเช่น ให้ใช้กฎความปลอดภัยต่อไปนี้

service firebase.storage {
  match /b/{bucket}/o {
    // Allow the client to read files with contentType 'image/png'
    match /aFileNamePrefix/{aFileName} {
      allow read: if resource.contentType == 'image/png';
    }
  }
}

ปฏิเสธ: กฎนี้ปฏิเสธรายการต่อไปนี้ เนื่องจากชุดผลลัพธ์สามารถรวมไฟล์ที่ contentType อยู่ ไม่ใช่ image/png:

เว็บ
filesRef = storage.ref().child("aFilenamePrefix");

filesRef.listAll()
    .then(function(result) {
      console.log("Success: ", result.items);
    })
});

กฎในCloud Storage Security Rulesจะประเมินคำค้นหาแต่ละรายการตามศักยภาพ ไม่สำเร็จและดำเนินการตามคำขอไม่สำเร็จ หากสามารถแสดงผลไฟล์ที่ไคลเอ็นต์ดำเนินการ ไม่มีสิทธิ์อ่าน คำขอเข้าถึงต้องเป็นไปตามข้อจำกัดที่กำหนดโดย กฎของคุณได้

ขั้นตอนถัดไป

คุณสามารถทำความเข้าใจ Firebase Security Rules ให้ลึกซึ้งยิ่งขึ้นสำหรับ Cloud Storage:

  • เรียนรู้แนวคิดหลักถัดไปของภาษากฎ นั่นคือแบบไดนามิก เงื่อนไข ซึ่งให้กฎของคุณตรวจสอบการให้สิทธิ์ของผู้ใช้ เปรียบเทียบข้อมูลที่มีอยู่กับข้อมูลขาเข้า ตรวจสอบข้อมูลที่เข้ามาใหม่ และอื่นๆ

  • ตรวจสอบกรณีการใช้งานด้านความปลอดภัยทั่วไป Firebase Security Rules คำจำกัดความที่อธิบายถึงพวกเขาได้

คุณสามารถดูกรณีการใช้งาน Firebase Security Rules สําหรับ Cloud Storage โดยเฉพาะได้ดังนี้