Quy tắc bảo mật cho các hoạt động của quy trình

Mặc dù các thao tác trong quy trình cung cấp một tập hợp tính năng phong phú, nhưng công cụ Quy tắc chỉ nhận dạng các bộ lọc so sánh (ví dụ: >) và bộ lọc logic (ví dụ: or) để đảm bảo tính thoả mãn ràng buộc và tính bảo mật.

Biểu thức bộ lọc được hỗ trợ

Để các thao tác trong quy trình bị ràng buộc trong phạm vi do quy tắc của bạn đặt ra, các thao tác này phải sử dụng toán tử logic và toán tử so sánh đối với các hằng số. Công cụ Quy tắc nhận dạng các loại bộ lọc sau:

  • So sánh: eq, neq, gt, gte, lt, lte, in, arrayContains.
  • Logic: and, or.

Dưới đây là một số ví dụ:

  • where(eq("foo", 2))
  • where(lt("foo", 2))
  • documents("/user/1", "/user/2").where(...)

Thuộc tính yêu cầu

Bạn có thể tiếp tục sử dụng đối tượng request để xác thực ngữ cảnh truy vấn và xác thực, mặc dù một số thuộc tính có trong các truy vấn tiêu chuẩn không được hỗ trợ trong các thao tác trong quy trình.

Thuộc tính được hỗ trợ

Công cụ mới tiếp tục hỗ trợ các thuộc tính sau:

  • request.auth: Truy cập vào dữ liệu mã thông báo và mã nhận dạng người dùng.
  • request.method: Xác định thao tác (Ví dụ: get, list).
  • request.path: Đường dẫn của tài nguyên đang được truy cập.
  • request.time: Dấu thời gian phía máy chủ của yêu cầu.

Thuộc tính không được hỗ trợ

Các thuộc tính request.query như limit, offsetorderBy không được hỗ trợ cho các quy tắc kiểm tra thao tác trong quy trình do độ phức tạp của việc xác định các giá trị này trong các truy vấn nhiều giai đoạn.

Xử lý giai đoạn quy trình và quyền

Có nhiều giai đoạn quy trình ánh xạ đến các thao tác chi tiết cụ thể trong quy tắc bảo mật:

  • Quyền allow list: Được kích hoạt bởi các giai đoạn collection(), collectionGroup()database().
  • Quyền allow get: Được kích hoạt bởi giai đoạn documents(), được xử lý tương tự như thao tác get hàng loạt.
  • Giai đoạn ký tự: Giai đoạn literals() không đọc từ cơ sở dữ liệu nhưng có thể phát sinh chi phí. Để ngăn chặn hành vi lạm dụng, giai đoạn này phải được ghép nối với một giai đoạn khác (như collection()) có thể được quy tắc xác minh.

Giai đoạn sửa đổi trường

Quy tắc chỉ hoạt động trên dữ liệu được lưu trữ chứ không phải giá trị được suy ra. Nếu một quy trình bao gồm các giai đoạn sửa đổi trường (Ví dụ: add_fields(...), replace_with(...), select(...), remove_fields(...)), thì công cụ Quy tắc sẽ ngừng áp dụng các ràng buộc bộ lọc sau khi gặp giai đoạn đó. Để đảm bảo quy tắc hoạt động như mong đợi, hãy đặt các giai đoạn bộ lọc (tức là where) trước mọi giai đoạn có thể sửa đổi tài liệu được lưu trữ ban đầu.

Ví dụ: hãy xem quy tắc bảo mật sau:

match /databases/{database}/documents {
  match /cities/{city} {
    // Allow the user to read data if the document has the 'visibility'
    // field set to 'public'
    allow read: if resource.data.visibility == 'public';
  }
}

Bị từ chối: Quy tắc này từ chối quy trình sau vì giai đoạn addFields xảy ra trước khi lọc để tìm tài liệu có visibilitypublic:

const results = await db.pipeline()
  .collection("/cities")
  // Filters after a modification stage are ignored by Rules.
  .addFields(constant(1000).as("population"))
  .where(eq(field("visibility"), constant("public")))
  .execute();

Được phép: Quy tắc này cho phép quy trình sau vì giai đoạn where(eq(field("visibility"), constant("public"))) xảy ra trước mọi giai đoạn sửa đổi:

const results = await db.pipeline()
  .collection("/cities")
  .where(eq(field("visibility"), constant("public")))
  .addFields(constant(1000).as("population"))
  .execute();