Tìm hiểu cú pháp cốt lõi của ngôn ngữ Quy tắc bảo mật của Firebase dành cho Cloud Storage

Quy tắc bảo mật của Firebase dành cho Cloud Storage giúp bạn kiểm soát quyền truy cập vào các đối tượng được lưu trữ trong bộ chứa Cloud Storage. Cú pháp quy tắc linh hoạt cho phép bạn tạo các quy tắc để kiểm soát mọi thao tác, từ mọi lượt ghi vào Cloud Storage bộ chứa cho các thao tác trên một tệp cụ thể.

Hướng dẫn này mô tả cú pháp và cấu trúc cơ bản của Quy tắc bảo mật của Cloud Storage để tạo bộ quy tắc hoàn chỉnh.

Khai báo dịch vụ và cơ sở dữ liệu

Quy tắc bảo mật của Firebase dành cho Cloud Storage luôn bắt đầu bằng nội dung khai báo sau:

service firebase.storage {
    // ...
}

Nội dung khai báo service firebase.storage đặt phạm vi của các quy tắc thành Cloud Storage, ngăn chặn xung đột giữa các Quy tắc bảo mật của Cloud Storage và cho các sản phẩm khác như Cloud Firestore.

Quy tắc đọc/ghi cơ bản

Các quy tắc cơ bản bao gồm một câu lệnh match xác định Cloud Storage nhóm, một câu lệnh khớp chỉ định tên tệp và biểu thức allow cho phép thông tin chi tiết khi đọc dữ liệu cụ thể. allow biểu thức chỉ định các phương thức truy cập (ví dụ: đọc, ghi) có liên quan và điều kiện mà trong đó quyền truy cập sẽ được cho phép hoặc bị từ chối.

Trong bộ quy tắc mặc định, câu lệnh match đầu tiên sử dụng ký tự đại diện {bucket} để cho biết các quy tắc áp dụng cho tất cả các nhóm trong dự án của bạn. Chúng tôi sẽ hãy thảo luận thêm về ý tưởng kết hợp ký tự đại diện trong phần tiếp theo.

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>;
    }
  }
}

Tất cả câu lệnh trùng khớp đều trỏ đến tệp. Câu lệnh so khớp có thể trỏ đến một thông tin như trong match /images/profilePhoto.png.

Khớp với ký tự đại diện

Ngoài việc trỏ đến một tệp duy nhất, Quy tắc có thể sử dụng ký tự đại diện để trỏ đến bất kỳ tệp nào có tiền tố chuỗi cho trước trong tên, bao gồm cả dấu gạch chéo, như trong match /images/{imageId}.

Trong ví dụ trên, câu lệnh so khớp sử dụng cú pháp ký tự đại diện {imageId}. Tức là quy tắc này áp dụng cho mọi tệp có /images/ ở đầu tên, chẳng hạn như /images/profilePhoto.png hoặc /images/croppedProfilePhoto.png. Khi Biểu thức allow trong câu lệnh so khớp được đánh giá, biến imageId sẽ phân giải thành tên tệp hình ảnh, chẳng hạn như profilePhoto.png hoặc croppedProfilePhoto.png.

Bạn có thể tham chiếu biến ký tự đại diện từ trong match để cung cấp tệp uỷ quyền tên hoặc đường dẫn:

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

Dữ liệu phân cấp

Như chúng tôi đã nói trước đó, không có cấu trúc phân cấp bên trong Bộ chứa Cloud Storage. Nhưng bằng cách sử dụng quy ước đặt tên tệp, thường là bao gồm dấu gạch chéo trong tên tệp, chúng ta có thể bắt chước cấu trúc giống như một loạt thư mục và thư mục con lồng nhau. Điều quan trọng là phải hiểu rõ cách Quy tắc bảo mật của Firebase tương tác với những tên tệp này.

Hãy xem xét tình huống của một tập hợp các tệp có tên đều bắt đầu bằng /images/ thân cây. Quy tắc bảo mật của Firebase chỉ áp dụng cho tên tệp trùng khớp, do đó, quyền truy cập các thành phần điều khiển được xác định trên thân /images/ không áp dụng cho /mp3s/. Thay vào đó, hãy viết các quy tắc rõ ràng khớp với nhiều mẫu tên tệp:

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>;
    }
  }
}

Khi lồng các câu lệnh match, đường dẫn của câu lệnh match bên trong là luôn được thêm vào đường dẫn của câu lệnh match bên ngoài. Nội dung sau đây do đó, hai bộ quy tắc tương đương với nhau:

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>;
      }
  }
}

Ký tự đại diện trùng khớp đệ quy

Ngoài các ký tự đại diện khớp và trả về chuỗi ở cuối tên tệp, bạn có thể khai báo một ký tự đại diện nhiều phân đoạn để so khớp phức tạp hơn bằng cách thêm =** vào tên ký tự đại diện, chẳng hạn như {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>;
  }
}

Nếu nhiều quy tắc khớp với một tệp, kết quả sẽ là OR trong kết quả của tất cả đánh giá quy tắc. Nghĩa là, nếu bất kỳ quy tắc nào mà tệp phù hợp có kết quả là true, kết quả là true

Trong các quy tắc trên, tệp "images/profilePhotos.png" có thể đọc được nếu condition hoặc other_condition cho kết quả là true, trong khi tệp "images/users/user:12345/profilePhoto.png" chỉ phải tuân theo kết quả của other_condition.

Các quy tắc bảo mật của Cloud Storage không phân tầng và các quy tắc chỉ được đánh giá khi đường dẫn yêu cầu khớp với một đường dẫn có quy tắc được chỉ định.

Phiên bản 1

Quy tắc bảo mật của Firebase sử dụng phiên bản 1 theo mặc định. Trong phiên bản 1, ký tự đại diện đệ quy khớp với một hoặc nhiều phần tử tên tệp, chứ không phải không có hoặc nhiều phần tử. Do đó, match /images/{filenamePrefixWildcard}/{imageFilename=**} khớp với tên tệp như /images/profilePics/profile.png, chứ không phải /images/badge.png. Sử dụng Hãy /images/{imagePrefixorFilename=**}.

Ký tự đại diện đệ quy phải ở cuối câu lệnh so khớp.

Bạn nên sử dụng phiên bản 2 để có thêm nhiều tính năng mạnh mẽ hơn.

Phiên bản 2

Trong phiên bản 2 của Quy tắc bảo mật Firebase, các ký tự đại diện đệ quy khớp với đường dẫn từ 0 trở lên mục. Do đó, /images/{filenamePrefixWildcard}/{imageFilename=**} trùng khớp với tên tệp /images/profilePics/profile.png và /images/badge.png.

Bạn phải chọn sử dụng phiên bản 2 bằng cách thêm rules_version = '2'; ở đầu quy tắc bảo mật của bạn:

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

Bạn có thể có tối đa một ký tự đại diện đệ quy cho mỗi câu lệnh khớp, nhưng trong phiên bản 2, bạn có thể đặt ký tự đại diện này ở bất cứ đâu trong câu lệnh so khớp. Để ví dụ:

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>;
   }
  }
}

Toán tử chi tiết

Trong một số trường hợp, bạn nên chia readwrite thành nhiều hơn các hoạt động chi tiết hơn. Ví dụ: ứng dụng của bạn có thể muốn thực thi các chế độ cài đặt khác nhau điều kiện tạo tệp so với điều kiện xoá tệp.

Toán tử read có thể được chia thành getlist.

Một quy tắc write có thể là được chia thành create, updatedelete:

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>;
    }
  }
 }
}

Câu lệnh trùng khớp chồng chéo

Một tên tệp có thể khớp với nhiều câu lệnh match. Trong trong trường hợp nhiều biểu thức allow khớp với một yêu cầu, thì quyền truy cập sẽ được cho phép nếu bất kỳ điều kiện nào là 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;
    }
  }
}

Trong ví dụ trên, tất cả lượt đọc và ghi vào các tệp có tên bắt đầu bằng /images/ được phép vì quy tắc thứ hai luôn là true, ngay cả khi quy tắc đầu tiên là false.

Quy tắc không phải là bộ lọc

Sau khi bạn bảo mật dữ liệu của mình và bắt đầu thực hiện các thao tác với tệp, hãy ghi nhớ rằng quy tắc bảo mật không phải là bộ lọc. Bạn không thể thực hiện thao tác trên một tập hợp các tệp khớp với mẫu tên tệp và yêu cầu Cloud Storage chỉ truy cập các tệp mà ứng dụng hiện tại có quyền truy cập.

Ví dụ: dùng quy tắc bảo mật sau:

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';
    }
  }
}

Đã từ chối: Quy tắc này từ chối nội dung sau vì tập hợp kết quả có thể bao gồm các tệp trong đó contentType không phải image/png:

Web
filesRef = storage.ref().child("aFilenamePrefix");

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

Các quy tắc trong Quy tắc bảo mật của Cloud Storage đánh giá từng truy vấn theo tiềm năng kết quả và không thực hiện được yêu cầu nếu có thể trả về một tệp mà ứng dụng khách không có quyền đọc. Các yêu cầu truy cập phải tuân theo những ràng buộc do các quy tắc của mình.

Các bước tiếp theo

Bạn có thể hiểu rõ hơn về Quy tắc bảo mật của Firebase cho Cloud Storage:

  • Tìm hiểu khái niệm chính tiếp theo về ngôn ngữ của Quy tắc, linh động điều kiện, cho phép Quy tắc của bạn kiểm tra sự cho phép của người dùng, so sánh dữ liệu hiện có và dữ liệu đầu vào, xác thực dữ liệu đầu vào, v.v.

  • Xem các trường hợp sử dụng bảo mật điển hình và Định nghĩa về các quy tắc bảo mật của Firebase.

Bạn có thể khám phá các trường hợp sử dụng Quy tắc bảo mật của Firebase dành riêng cho Cloud Storage: