Catch up on everything announced at Firebase Summit, and learn how Firebase can help you accelerate app development and run your app with confidence. Learn More

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

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

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

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

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

กฎความปลอดภัยของ Firebase สำหรับ Cloud Storage เริ่มต้นด้วยการประกาศต่อไปนี้เสมอ:

service firebase.storage {
    // ...
}

การประกาศ service firebase.storage จะกำหนดขอบเขตกฎไปยัง Cloud Storage เพื่อป้องกันความขัดแย้งระหว่างกฎความปลอดภัยของ Cloud Storage และกฎสำหรับผลิตภัณฑ์อื่นๆ เช่น 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

จับคู่สัญลักษณ์แทน

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

พิจารณาสถานการณ์ของชุดของไฟล์ที่มีชื่อที่ขึ้นต้นด้วย /images/ ต้นกำเนิด กฎความปลอดภัยของ Firebase มีผลกับชื่อไฟล์ที่ตรงกันเท่านั้น ดังนั้นการควบคุมการเข้าถึงที่กำหนดไว้ใน /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 หรือเงื่อนไขอื่น ๆ ประเมินว่าเป็นจริง ในขณะที่ไฟล์ "images/users/user:12345/profilePhoto.png" จะขึ้นอยู่กับผลลัพธ์ของ other_condition other_condition .

กฎความปลอดภัยของ Cloud Storage ไม่ต่อเรียง และกฎจะได้รับการประเมินเมื่อเส้นทางคำขอตรงกับเส้นทางที่มีกฎที่ระบุเท่านั้น

เวอร์ชั่น 1

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

สัญลักษณ์แทนแบบเรียกซ้ำต้องอยู่ท้ายคำสั่งการแข่งขัน

เราขอแนะนำให้คุณใช้เวอร์ชัน 2 สำหรับคุณลักษณะที่มีประสิทธิภาพยิ่งขึ้น

รุ่น2

ในเวอร์ชัน 2 ของกฎความปลอดภัยของ Firebase ไวด์การ์ดแบบเรียกซ้ำจะจับคู่รายการพาธศูนย์หรือมากกว่า ดังนั้น /images/{filenamePrefixWildcard}/{imageFilename=**} จะจับคู่ชื่อไฟล์ /images/profilePics/profile.png และ /images/badge.png

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

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

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

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

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

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

  • ตรวจสอบกรณีการใช้งานการรักษาความปลอดภัยทั่วไปและ คำจำกัดความกฎความปลอดภัยของ Firebase ที่ กล่าวถึง

คุณสำรวจกรณีการใช้งาน Firebase Security Rule เฉพาะสำหรับ Cloud Storage ได้ดังนี้