Catch up on everthing we announced at this year's Firebase Summit. Learn more

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

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

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

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

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

service firebase.storage {
    // ...
}

service firebase.storage ประกาศขอบเขตกฎระเบียบในการจัดเก็บเมฆป้องกันไม่ให้ความขัดแย้งระหว่างการจัดเก็บเมฆกฎการรักษาความปลอดภัยและกฎระเบียบสำหรับผลิตภัณฑ์อื่น ๆ เช่นเมฆ FireStore

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

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

ใน ruleset เริ่มต้นของคุณเป็นครั้งแรกที่ 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

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

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

ในกฎระเบียบดังกล่าวข้างต้นที่ไฟล์ "images / profilePhoto.png" สามารถอ่านได้ถ้าทั้ง condition หรือ other_condition ประเมินให้เป็นจริงในขณะที่ไฟล์ "images / ผู้ใช้ / ผู้ใช้: 12345 / profilePhoto.png" เป็นเพียงเรื่องที่ผลของ 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 document 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 nonexistent files
      allow create: if <condition>;

      // Applies to updates to 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 any filename containing string '/images/'.
    match /images/{imageId} {
      allow read, write: if false;
    }

    // Matches all filenames containing string `/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 Security Rule เฉพาะสำหรับ Cloud Storage ได้ดังนี้