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 เพื่อสร้างชุดกฎที่สมบูรณ์

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

กฎความปลอดภัยของ 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

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

นอกเหนือจากการชี้ไปที่ไฟล์เดียว 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 โต้ตอบกับชื่อไฟล์เหล่านี้อย่างไร

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

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 ไม่เรียงซ้อน และกฎจะได้รับการประเมินเมื่อเส้นทางคำขอตรงกับเส้นทางที่มีกฎระบุไว้เท่านั้น

รุ่น 1

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

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

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

เวอร์ชัน 2

ในกฎความปลอดภัยของ Firebase เวอร์ชัน 2 สัญลักษณ์ตัวแทนแบบเรียกซ้ำจะจับคู่รายการเส้นทางตั้งแต่ศูนย์ขึ้นไป ดังนั้น /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);
    })
});

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

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

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

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

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

คุณสามารถสำรวจกรณีการใช้กฎความปลอดภัยของ Firebase เฉพาะสำหรับ Cloud Storage: