Join us for Firebase Summit on November 10, 2021. Tune in to learn how Firebase can help you accelerate app development, release with confidence, and scale with ease. Register

Ngôn ngữ quy tắc bảo mật

Các quy tắc bảo mật của Firebase tận dụng các ngôn ngữ tùy chỉnh, mạnh mẽ, linh hoạt hỗ trợ nhiều mức độ phức tạp và chi tiết. Bạn có thể làm cho Quy tắc cụ thể hoặc chung chung phù hợp với ứng dụng của mình. Các quy tắc Cơ sở dữ liệu thời gian thực sử dụng cú pháp giống như JavaScript trong cấu trúc JSON. Đám mây FireStore và Cloud Storage quy tắc sử dụng một ngôn ngữ dựa trên các biểu thức Common Language (CEL) , được xây dựng trên CEL với matchallow báo cáo rằng sự ủng hộ có điều kiện cấp quyền truy cập.

Vì đây là những ngôn ngữ tùy chỉnh, tuy nhiên, có một đường cong học tập. Sử dụng hướng dẫn này để hiểu rõ hơn về ngôn ngữ Quy tắc khi bạn đi sâu hơn vào các quy tắc phức tạp hơn.

Chọn một sản phẩm để tìm hiểu thêm về các quy tắc của nó.

Cấu trúc cơ bản

Cloud Firestore

Quy tắc bảo mật Firebase trong Cloud Firestore và Cloud Storage sử dụng cấu trúc và cú pháp sau:

service <<name>> {
  // Match the resource path.
  match <<path>> {
    // Allow the request if the following conditions are true.
    allow <<methods>> : if <<condition>>
  }
}

Các khái niệm chính sau đây rất quan trọng cần hiểu khi bạn xây dựng các quy tắc:

  • Yêu cầu: Các phương pháp hoặc các phương pháp áp dụng trong các allow tuyên bố. Đây là những phương pháp bạn đang cho phép chạy. Các phương pháp tiêu chuẩn là: get , list , create , update , và delete . Các readwrite các phương pháp tiện lợi cho phép rộng đọc và viết truy cập vào cơ sở dữ liệu hoặc lưu trữ đường dẫn cụ thể.
  • Đường dẫn: Cơ sở dữ liệu hoặc lưu trữ vị trí, biểu diễn dưới dạng một con đường URI.
  • Rule: Các allow tuyên bố, trong đó bao gồm một điều kiện cho phép yêu cầu nếu nó trả về true.

Mỗi khái niệm này được mô tả chi tiết hơn bên dưới.

Lưu trữ đám mây

Quy tắc bảo mật Firebase trong Cloud Firestore và Cloud Storage sử dụng cấu trúc và cú pháp sau:

service <<name>> {
  // Match the resource path.
  match <<path>> {
    // Allow the request if the following conditions are true.
    allow <<methods>> : if <<condition>>
  }
}

Các khái niệm chính sau đây rất quan trọng cần hiểu khi bạn xây dựng các quy tắc:

  • Yêu cầu: Các phương pháp hoặc các phương pháp áp dụng trong các allow tuyên bố. Đây là những phương pháp bạn đang cho phép chạy. Các phương pháp tiêu chuẩn là: get , list , create , update , và delete . Các readwrite các phương pháp tiện lợi cho phép rộng đọc và viết truy cập vào cơ sở dữ liệu hoặc lưu trữ đường dẫn cụ thể.
  • Đường dẫn: Cơ sở dữ liệu hoặc lưu trữ vị trí, biểu diễn dưới dạng một con đường URI.
  • Rule: Các allow tuyên bố, trong đó bao gồm một điều kiện cho phép yêu cầu nếu nó trả về true.

Mỗi khái niệm này được mô tả chi tiết hơn bên dưới.

Cơ sở dữ liệu thời gian thực

Trong Cơ sở dữ liệu thời gian thực, Quy tắc bảo mật Firebase bao gồm các biểu thức giống JavaScript có trong tài liệu JSON.

Họ sử dụng cú pháp sau:

{
  "rules": {
    "<<path>>": {
    // Allow the request if the condition for each method is true.
      ".read": <<condition>>,
      ".write": <<condition>>,
      ".validate": <<condition>>
    }
  }
}

Có ba yếu tố cơ bản trong quy tắc:

  • Đường dẫn: Vị trí cơ sở dữ liệu. Điều này phản ánh cấu trúc JSON của cơ sở dữ liệu của bạn.
  • Yêu cầu: Đây là những phương pháp sử dụng các quy tắc để cấp quyền truy cập. Các readwrite quy tắc cấp đọc rộng và truy cập ghi, trong khi validate quy tắc hoạt động như một xác minh thứ để cho phép truy cập dựa trên dữ liệu đến hoặc hiện tại.
  • Tình trạng: Điều kiện cho phép yêu cầu nếu nó trả về true.

Cấu trúc quy tắc

Cloud Firestore

Các yếu tố cơ bản của quy tắc trong Cloud Firestore và Cloud Storage như sau:

  • Các service khai: Khai báo các sản phẩm căn cứ hỏa lực các quy tắc áp dụng cho.
  • Các match khối: Định nghĩa một con đường trong cơ sở dữ liệu hoặc lưu trữ xô các quy tắc áp dụng cho.
  • Các allow tuyên bố: Cung cấp điều kiện để cấp quyền truy cập, phân biệt bằng phương pháp này. Các phương pháp hỗ trợ bao gồm: get , list , create , update , delete , và các phương pháp thuận tiện readwrite .
  • Tùy chọn function khai báo: Cung cấp khả năng kết hợp và quấn điều kiện để sử dụng trên nhiều quy tắc.

Các service chứa một hoặc nhiều match khối với allow báo cáo cung cấp điều kiện cấp quyền truy cập đến các yêu cầu. Các requestresource các biến có sẵn để sử dụng trong điều kiện quy tắc. Ngôn ngữ Quy định căn cứ hỏa lực an ninh cũng hỗ trợ function khai báo.

Phiên bản cú pháp

Các syntax câu lệnh chỉ ra phiên bản của ngôn ngữ căn cứ hỏa lực Nội quy sử dụng để viết mã nguồn. Phiên bản mới nhất của ngôn ngữ là v2 .

rules_version = '2';
service cloud.firestore {
...
}

Nếu không có rules_version tuyên bố được cung cấp, quy tắc của bạn sẽ được đánh giá bằng cách sử dụng v1 động cơ.

Dịch vụ

Các service định nghĩa khai mà căn cứ hỏa lực sản phẩm, hoặc dịch vụ, quy tắc của bạn áp dụng cho. Bạn chỉ có thể bao gồm một service khai cho mỗi tập tin nguồn.

Cloud Firestore

service cloud.firestore {
 // Your 'match' blocks with their corresponding 'allow' statements and
 // optional 'function' declarations are contained here
}

Lưu trữ đám mây

service firebase.storage {
  // Your 'match' blocks with their corresponding 'allow' statements and
  // optional 'function' declarations are contained here
}

Nếu bạn đang xác định các quy tắc cho cả Cloud Firestore và Cloud Storage bằng cách sử dụng Firebase CLI, bạn sẽ phải duy trì chúng trong các tệp riêng biệt.

Trận đấu

Một match khối khai báo một path hoa văn được khớp với đường dẫn cho các hoạt động yêu cầu (các đến request.path ). Cơ thể của match phải có một hoặc lồng nhau nhiều match khối, allow báo cáo, hoặc function khai báo. Đường dẫn trong lồng nhau match khối là liên quan đến con đường trong các phụ huynh match khối.

Các path mô hình là một tên thư mục giống như có thể bao gồm các biến hoặc các kí hiệu. Các path hoa văn cho phép đối với phân khúc đơn đường và các trận đấu phân khúc đa đường. Bất kỳ biến bị ràng buộc trong một path có thể nhìn thấy trong match phạm vi hoặc bất kỳ phạm vi lồng nhau nơi path được khai báo.

Trận đấu chống lại một path hoa văn có thể một phần hoặc toàn:

  • Trận đấu phần: Các path mô hình là một tiền tố trận đấu của request.path .
  • Trận đấu trọn vẹn: Các path hoa văn phù hợp với toàn bộ request.path .

Khi một trận đấu hoàn toàn được làm bằng các quy tắc trong khối được đánh giá. Khi một trận đấu một phần được làm bằng các lồng nhau match quy được kiểm tra để xem liệu bất kỳ lồng nhau path sẽ hoàn thành trận đấu.

Các quy tắc trong mỗi hoàn toàn match được đánh giá để xác định xem có nên cho phép yêu cầu. Nếu bất kỳ quy tắc phù hợp nào cấp quyền truy cập, yêu cầu được cho phép. Nếu không có quy tắc phù hợp nào cấp quyền truy cập, yêu cầu sẽ bị từ chối.

// Given request.path == /example/hello/nested/path the following
// declarations indicate whether they are a partial or complete match and
// the value of any variables visible within the scope.
service firebase.storage {
  // Partial match.
  match /example/{singleSegment} {   // `singleSegment` == 'hello'
    allow write;                     // Write rule not evaluated.
    // Complete match.
    match /nested/path {             // `singleSegment` visible in scope.
      allow read;                    // Read rule is evaluated.
    }
  }
  // Complete match.
  match /example/{multiSegment=**} { // `multiSegment` == /hello/nested/path
    allow read;                      // Read rule is evaluated.
  }
}

Như ví dụ trên cho thấy, path khai hỗ trợ các biến sau:

  • Single-phân khúc wildcard: Biến ký tự đại diện được khai báo trong một con đường bằng cách quấn một biến trong dấu ngoặc nhọn: {variable} . Biến này có thể truy cập trong match tuyên bố như một string .
  • Wildcard đệ quy: Các đệ quy, hoặc nhiều giai đoạn, trận đấu wildcard nhiều đoạn đường bằng hoặc thấp hơn một con đường. Ký tự đại diện này khớp với tất cả các đường dẫn bên dưới vị trí bạn đặt. Bạn có thể khai báo nó bằng cách thêm =** chuỗi vào cuối biến phân khúc của bạn: {variable=**} . Biến này có thể truy cập trong match tuyên bố như một path đối tượng.

Cho phép

Các match khối chứa một hoặc nhiều allow báo cáo. Đây là những quy tắc thực tế của bạn. Bạn có thể áp dụng allow quy tắc cho một hoặc nhiều phương pháp. Các điều kiện trên allow tuyên bố phải đánh giá là true Cloud FireStore hoặc Cloud Storage cấp bất kỳ yêu cầu đến. Bạn cũng có thể ghi allow báo cáo mà không cần điều kiện, ví dụ, allow read . Nếu allow tuyên bố không bao gồm một điều kiện, tuy nhiên, nó luôn luôn cho phép các yêu cầu đối với phương thức đó.

Nếu bất kỳ allow quy tắc cho phương pháp này được đáp ứng, yêu cầu được cho phép. Ngoài ra, nếu quy tắc rộng hơn cấp quyền truy cập, Quy tắc cấp quyền truy cập và bỏ qua bất kỳ quy tắc chi tiết nào có thể hạn chế quyền truy cập.

Hãy xem xét ví dụ sau, nơi bất kỳ người dùng nào cũng có thể đọc hoặc xóa bất kỳ tệp nào của riêng họ. Quy tắc chi tiết hơn chỉ cho phép ghi nếu người dùng yêu cầu ghi sở hữu tệp và tệp là PNG. Người dùng có thể xóa bất kỳ tệp nào tại đường dẫn con - ngay cả khi chúng không phải là PNG - bởi vì quy tắc trước đó cho phép điều đó.

service firebase.storage {
  // Allow the requestor to read or delete any resource on a path under the
  // user directory.
  match /users/{userId}/{anyUserFile=**} {
    allow read, delete: if request.auth != null && request.auth.uid == userId;
  }

  // Allow the requestor to create or update their own images.
  // When 'request.method' == 'delete' this rule and the one matching
  // any path under the user directory would both match and the `delete`
  // would be permitted.

  match /users/{userId}/images/{imageId} {
    // Whether to permit the request depends on the logical OR of all
    // matched rules. This means that even if this rule did not explicitly
    // allow the 'delete' the earlier rule would have.
    allow write: if request.auth != null && request.auth.uid == userId && imageId.matches('*.png');
  }
}

Phương pháp

Mỗi allow tuyên bố bao gồm một phương pháp mà cấp quyền truy cập cho các yêu cầu đến các phương pháp tương tự.

Phương pháp Loại yêu cầu
Phương pháp tiện lợi
read Bất kỳ loại yêu cầu đọc nào
write Bất kỳ loại yêu cầu viết nào
Phương pháp tiêu chuẩn
get Đọc các yêu cầu đối với các tài liệu hoặc tệp đơn lẻ
list Đọc yêu cầu cho các truy vấn và bộ sưu tập
create Viết tài liệu hoặc tệp mới
update Ghi vào tài liệu cơ sở dữ liệu hiện có hoặc cập nhật siêu dữ liệu tệp
delete Xóa dữ liệu

Bạn có thể không chồng chéo đọc phương pháp trong cùng một match khối hoặc mâu thuẫn phương pháp ghi trong cùng một path khai.

Ví dụ: các quy tắc sau sẽ không thành công:

service bad.example {
  match /rules/with/overlapping/methods {
    // This rule allows reads to all authenticated users
    allow read: if request.auth != null;

    match another/subpath {
      // This secondary, more specific read rule causes an error
      allow get: if request.auth != null && request.auth.uid == "me";
      // Overlapping write methods in the same path cause an error as well
      allow write: if request.auth != null;
      allow create: if request.auth != null && request.auth.uid == "me";
    }
  }
}

Hàm số

Khi các quy tắc bảo mật của bạn trở nên phức tạp hơn, bạn có thể muốn bao bọc các nhóm điều kiện trong các hàm mà bạn có thể sử dụng lại trên bộ quy tắc của mình. Các quy tắc bảo mật hỗ trợ các chức năng tùy chỉnh. Cú pháp cho các hàm tùy chỉnh hơi giống JavaScript, nhưng các hàm quy tắc bảo mật được viết bằng ngôn ngữ dành riêng cho miền có một số hạn chế quan trọng:

  • Chức năng có thể chứa chỉ có một return tuyên bố. Chúng không thể chứa bất kỳ logic bổ sung nào. Ví dụ, chúng không thể thực hiện các vòng lặp hoặc gọi các dịch vụ bên ngoài.
  • Các hàm có thể tự động truy cập các hàm và biến từ phạm vi mà chúng được xác định. Ví dụ, một chức năng được xác định trong phạm vi service cloud.firestore phạm vi có quyền truy cập vào các resource khác nhau và tích hợp các chức năng như get()exists() .
  • Các hàm có thể gọi các hàm khác nhưng không thể đệ quy. Tổng chiều sâu ngăn xếp cuộc gọi được giới hạn ở 20.
  • Trong quy tắc phiên bản v2 , chức năng có thể định nghĩa biến bằng cách sử dụng let từ khóa. Các hàm có thể có tối đa 10 liên kết let, nhưng phải kết thúc bằng câu lệnh trả về.

Một chức năng được định nghĩa với function khóa và mất không hay nhiều đối số. Ví dụ: bạn có thể muốn kết hợp hai loại điều kiện được sử dụng trong các ví dụ trên thành một hàm duy nhất:

service cloud.firestore {
  match /databases/{database}/documents {
    // True if the user is signed in or the requested data is 'public'
    function signedInOrPublic() {
      return request.auth.uid != null || resource.data.visibility == 'public';
    }

    match /cities/{city} {
      allow read, write: if signedInOrPublic();
    }

    match /users/{user} {
      allow read, write: if signedInOrPublic();
    }
  }
}

Đây là một ví dụ hiển thị các đối số của hàm và phép gán. Các câu lệnh gán phải được phân cách bằng dấu chấm phẩy.

function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
  return isAuthor || isAdmin;
}

Lưu ý cách isAdmin phân công thực thi một tra cứu của bộ sưu tập quản trị viên. Đối với đánh giá lười biếng mà không cần tra cứu không cần thiết, tận dụng lợi thế của tính chất ngắn circuiting của && (AND) và || (OR) so sánh để gọi một chức năng thứ hai chỉ khi isAuthor được chứng minh là đúng (ví && so sánh) hay sai (ví || so sánh).

function isAdmin(userId) {
  return exists(/databases/$(database)/documents/admins/$(userId));
}
function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  // `||` is short-circuiting; isAdmin called only if isAuthor == false.
  return isAuthor || isAdmin(userId);
}

Việc sử dụng các hàm trong các quy tắc bảo mật của bạn khiến chúng dễ bảo trì hơn khi mức độ phức tạp của các quy tắc của bạn ngày càng tăng.

Lưu trữ đám mây

Các yếu tố cơ bản của quy tắc trong Cloud Firestore và Cloud Storage như sau:

  • Các service khai: Khai báo các sản phẩm căn cứ hỏa lực các quy tắc áp dụng cho.
  • Các match khối: Định nghĩa một con đường trong cơ sở dữ liệu hoặc lưu trữ xô các quy tắc áp dụng cho.
  • Các allow tuyên bố: Cung cấp điều kiện để cấp quyền truy cập, phân biệt bằng phương pháp này. Các phương pháp hỗ trợ bao gồm: get , list , create , update , delete , và các phương pháp thuận tiện readwrite .
  • Tùy chọn function khai báo: Cung cấp khả năng kết hợp và quấn điều kiện để sử dụng trên nhiều quy tắc.

Các service chứa một hoặc nhiều match khối với allow báo cáo cung cấp điều kiện cấp quyền truy cập đến các yêu cầu. Các requestresource các biến có sẵn để sử dụng trong điều kiện quy tắc. Ngôn ngữ Quy định căn cứ hỏa lực an ninh cũng hỗ trợ function khai báo.

Phiên bản cú pháp

Các syntax câu lệnh chỉ ra phiên bản của ngôn ngữ căn cứ hỏa lực Nội quy sử dụng để viết mã nguồn. Phiên bản mới nhất của ngôn ngữ là v2 .

rules_version = '2';
service cloud.firestore {
...
}

Nếu không có rules_version tuyên bố được cung cấp, quy tắc của bạn sẽ được đánh giá bằng cách sử dụng v1 động cơ.

Dịch vụ

Các service định nghĩa khai mà căn cứ hỏa lực sản phẩm, hoặc dịch vụ, quy tắc của bạn áp dụng cho. Bạn chỉ có thể bao gồm một service khai cho mỗi tập tin nguồn.

Cloud Firestore

service cloud.firestore {
 // Your 'match' blocks with their corresponding 'allow' statements and
 // optional 'function' declarations are contained here
}

Lưu trữ đám mây

service firebase.storage {
  // Your 'match' blocks with their corresponding 'allow' statements and
  // optional 'function' declarations are contained here
}

Nếu bạn đang xác định các quy tắc cho cả Cloud Firestore và Cloud Storage bằng cách sử dụng Firebase CLI, bạn sẽ phải duy trì chúng trong các tệp riêng biệt.

Trận đấu

Một match khối khai báo một path hoa văn được khớp với đường dẫn cho các hoạt động yêu cầu (các đến request.path ). Cơ thể của match phải có một hoặc lồng nhau nhiều match khối, allow báo cáo, hoặc function khai báo. Đường dẫn trong lồng nhau match khối là liên quan đến con đường trong các phụ huynh match khối.

Các path mô hình là một tên thư mục giống như có thể bao gồm các biến hoặc các kí hiệu. Các path hoa văn cho phép đối với phân khúc đơn đường và các trận đấu phân khúc đa đường. Bất kỳ biến bị ràng buộc trong một path có thể nhìn thấy trong match phạm vi hoặc bất kỳ phạm vi lồng nhau nơi path được khai báo.

Trận đấu chống lại một path hoa văn có thể một phần hoặc toàn:

  • Trận đấu phần: Các path mô hình là một tiền tố trận đấu của request.path .
  • Trận đấu trọn vẹn: Các path hoa văn phù hợp với toàn bộ request.path .

Khi một trận đấu hoàn toàn được làm bằng các quy tắc trong khối được đánh giá. Khi một trận đấu một phần được làm bằng các lồng nhau match quy được kiểm tra để xem liệu bất kỳ lồng nhau path sẽ hoàn thành trận đấu.

Các quy tắc trong mỗi hoàn toàn match được đánh giá để xác định xem có nên cho phép yêu cầu. Nếu bất kỳ quy tắc phù hợp nào cấp quyền truy cập, yêu cầu được cho phép. Nếu không có quy tắc phù hợp nào cấp quyền truy cập, yêu cầu sẽ bị từ chối.

// Given request.path == /example/hello/nested/path the following
// declarations indicate whether they are a partial or complete match and
// the value of any variables visible within the scope.
service firebase.storage {
  // Partial match.
  match /example/{singleSegment} {   // `singleSegment` == 'hello'
    allow write;                     // Write rule not evaluated.
    // Complete match.
    match /nested/path {             // `singleSegment` visible in scope.
      allow read;                    // Read rule is evaluated.
    }
  }
  // Complete match.
  match /example/{multiSegment=**} { // `multiSegment` == /hello/nested/path
    allow read;                      // Read rule is evaluated.
  }
}

Như ví dụ trên cho thấy, path khai hỗ trợ các biến sau:

  • Single-phân khúc wildcard: Biến ký tự đại diện được khai báo trong một con đường bằng cách quấn một biến trong dấu ngoặc nhọn: {variable} . Biến này có thể truy cập trong match tuyên bố như một string .
  • Wildcard đệ quy: Các đệ quy, hoặc nhiều giai đoạn, trận đấu wildcard nhiều đoạn đường bằng hoặc thấp hơn một con đường. Ký tự đại diện này khớp với tất cả các đường dẫn bên dưới vị trí bạn đặt. Bạn có thể khai báo nó bằng cách thêm =** chuỗi vào cuối biến phân khúc của bạn: {variable=**} . Biến này có thể truy cập trong match tuyên bố như một path đối tượng.

Cho phép

Các match khối chứa một hoặc nhiều allow báo cáo. Đây là những quy tắc thực tế của bạn. Bạn có thể áp dụng allow quy tắc cho một hoặc nhiều phương pháp. Các điều kiện trên allow tuyên bố phải đánh giá là true Cloud FireStore hoặc Cloud Storage cấp bất kỳ yêu cầu đến. Bạn cũng có thể ghi allow báo cáo mà không cần điều kiện, ví dụ, allow read . Nếu allow tuyên bố không bao gồm một điều kiện, tuy nhiên, nó luôn luôn cho phép các yêu cầu đối với phương thức đó.

Nếu bất kỳ allow quy tắc cho phương pháp này được đáp ứng, yêu cầu được cho phép. Ngoài ra, nếu quy tắc rộng hơn cấp quyền truy cập, Quy tắc cấp quyền truy cập và bỏ qua bất kỳ quy tắc chi tiết nào có thể hạn chế quyền truy cập.

Hãy xem xét ví dụ sau, nơi bất kỳ người dùng nào cũng có thể đọc hoặc xóa bất kỳ tệp nào của riêng họ. Quy tắc chi tiết hơn chỉ cho phép ghi nếu người dùng yêu cầu ghi sở hữu tệp và tệp là PNG. Người dùng có thể xóa bất kỳ tệp nào tại đường dẫn con - ngay cả khi chúng không phải là PNG - bởi vì quy tắc trước đó cho phép điều đó.

service firebase.storage {
  // Allow the requestor to read or delete any resource on a path under the
  // user directory.
  match /users/{userId}/{anyUserFile=**} {
    allow read, delete: if request.auth != null && request.auth.uid == userId;
  }

  // Allow the requestor to create or update their own images.
  // When 'request.method' == 'delete' this rule and the one matching
  // any path under the user directory would both match and the `delete`
  // would be permitted.

  match /users/{userId}/images/{imageId} {
    // Whether to permit the request depends on the logical OR of all
    // matched rules. This means that even if this rule did not explicitly
    // allow the 'delete' the earlier rule would have.
    allow write: if request.auth != null && request.auth.uid == userId && imageId.matches('*.png');
  }
}

Phương pháp

Mỗi allow tuyên bố bao gồm một phương pháp mà cấp quyền truy cập cho các yêu cầu đến các phương pháp tương tự.

Phương pháp Loại yêu cầu
Phương pháp tiện lợi
read Bất kỳ loại yêu cầu đọc nào
write Bất kỳ loại yêu cầu viết nào
Phương pháp tiêu chuẩn
get Đọc các yêu cầu đối với các tài liệu hoặc tệp đơn lẻ
list Đọc yêu cầu cho các truy vấn và bộ sưu tập
create Viết tài liệu hoặc tệp mới
update Ghi vào tài liệu cơ sở dữ liệu hiện có hoặc cập nhật siêu dữ liệu tệp
delete Xóa dữ liệu

Bạn có thể không chồng chéo đọc phương pháp trong cùng một match khối hoặc mâu thuẫn phương pháp ghi trong cùng một path khai.

Ví dụ: các quy tắc sau sẽ không thành công:

service bad.example {
  match /rules/with/overlapping/methods {
    // This rule allows reads to all authenticated users
    allow read: if request.auth != null;

    match another/subpath {
      // This secondary, more specific read rule causes an error
      allow get: if request.auth != null && request.auth.uid == "me";
      // Overlapping write methods in the same path cause an error as well
      allow write: if request.auth != null;
      allow create: if request.auth != null && request.auth.uid == "me";
    }
  }
}

Hàm số

Khi các quy tắc bảo mật của bạn trở nên phức tạp hơn, bạn có thể muốn bao bọc các nhóm điều kiện trong các hàm mà bạn có thể sử dụng lại trên bộ quy tắc của mình. Các quy tắc bảo mật hỗ trợ các chức năng tùy chỉnh. Cú pháp cho các hàm tùy chỉnh hơi giống JavaScript, nhưng các hàm quy tắc bảo mật được viết bằng ngôn ngữ dành riêng cho miền có một số hạn chế quan trọng:

  • Chức năng có thể chứa chỉ có một return tuyên bố. Chúng không thể chứa bất kỳ logic bổ sung nào. Ví dụ, chúng không thể thực hiện các vòng lặp hoặc gọi các dịch vụ bên ngoài.
  • Các hàm có thể tự động truy cập các hàm và biến từ phạm vi mà chúng được xác định. Ví dụ, một chức năng được xác định trong phạm vi service cloud.firestore phạm vi có quyền truy cập vào các resource khác nhau và tích hợp các chức năng như get()exists() .
  • Các hàm có thể gọi các hàm khác nhưng không thể đệ quy. Tổng độ sâu ngăn xếp cuộc gọi được giới hạn ở 20.
  • Trong quy tắc phiên bản v2 , chức năng có thể định nghĩa biến bằng cách sử dụng let từ khóa. Các hàm có thể có tối đa 10 liên kết let, nhưng phải kết thúc bằng câu lệnh trả về.

Một chức năng được định nghĩa với function khóa và mất không hay nhiều đối số. Ví dụ: bạn có thể muốn kết hợp hai loại điều kiện được sử dụng trong các ví dụ trên thành một hàm duy nhất:

service cloud.firestore {
  match /databases/{database}/documents {
    // True if the user is signed in or the requested data is 'public'
    function signedInOrPublic() {
      return request.auth.uid != null || resource.data.visibility == 'public';
    }

    match /cities/{city} {
      allow read, write: if signedInOrPublic();
    }

    match /users/{user} {
      allow read, write: if signedInOrPublic();
    }
  }
}

Đây là một ví dụ hiển thị các đối số của hàm và phép gán. Các câu lệnh gán phải được phân cách bằng dấu chấm phẩy.

function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
  return isAuthor || isAdmin;
}

Lưu ý cách isAdmin phân công thực thi một tra cứu của bộ sưu tập quản trị viên. Đối với đánh giá lười biếng mà không cần tra cứu không cần thiết, tận dụng lợi thế của tính chất ngắn circuiting của && (AND) và || (OR) so sánh để gọi một chức năng thứ hai chỉ khi isAuthor được chứng minh là đúng (ví && so sánh) hay sai (ví || so sánh).

function isAdmin(userId) {
  return exists(/databases/$(database)/documents/admins/$(userId));
}
function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  // `||` is short-circuiting; isAdmin called only if isAuthor == false.
  return isAuthor || isAdmin(userId);
}

Việc sử dụng các hàm trong các quy tắc bảo mật của bạn giúp chúng dễ bảo trì hơn khi mức độ phức tạp của các quy tắc của bạn ngày càng tăng.

Cơ sở dữ liệu thời gian thực

Như đã nêu ở trên, Quy tắc cơ sở dữ liệu thời gian thực bao gồm ba yếu tố cơ bản: vị trí cơ sở dữ liệu như một bản sao của cấu trúc JSON của cơ sở dữ liệu, loại yêu cầu và điều kiện cấp quyền truy cập.

Vị trí cơ sở dữ liệu

Cấu trúc của các quy tắc của bạn phải tuân theo cấu trúc của dữ liệu bạn đã lưu trữ trong cơ sở dữ liệu của mình. Ví dụ: trong ứng dụng trò chuyện có danh sách tin nhắn, bạn có thể có dữ liệu giống như sau:

  {
    "messages": {
      "message0": {
        "content": "Hello",
        "timestamp": 1405704370369
      },
      "message1": {
        "content": "Goodbye",
        "timestamp": 1405704395231
      },
      ...
    }
  }

Các quy tắc của bạn nên phản ánh cấu trúc đó. Ví dụ:

  {
    "rules": {
      "messages": {
        "$message": {
          // only messages from the last ten minutes can be read
          ".read": "data.child('timestamp').val() > (now - 600000)",

          // new messages must have a string content and a number timestamp
          ".validate": "newData.hasChildren(['content', 'timestamp']) &&
                        newData.child('content').isString() &&
                        newData.child('timestamp').isNumber()"
        }
      }
    }
  }

Như ví dụ trên cho thấy, thời gian thực Cơ sở dữ liệu quy hỗ trợ $location biến để phù hợp với các đoạn đường. Sử dụng $ prefix trước phân khúc con đường của bạn để phù hợp với quy tắc của bạn cho bất kỳ nút con dọc theo con đường.

  {
    "rules": {
      "rooms": {
        // This rule applies to any child of /rooms/, the key for each room id
        // is stored inside $room_id variable for reference
        "$room_id": {
          "topic": {
            // The room's topic can be changed if the room id has "public" in it
            ".write": "$room_id.contains('public')"
          }
        }
      }
    }
  }

Bạn cũng có thể sử dụng $variable song song với tên đường dẫn không đổi.

  {
    "rules": {
      "widget": {
        // a widget can have a title or color attribute
        "title": { ".validate": true },
        "color": { ".validate": true },

        // but no other child paths are allowed
        // in this case, $other means any key excluding "title" and "color"
        "$other": { ".validate": false }
      }
    }
  }

Phương pháp

Trong Cơ sở dữ liệu thời gian thực, có ba loại quy tắc. Hai trong số các loại quy tắc - readwrite - áp dụng cho phương pháp của một yêu cầu đến. Các validate loại quy tắc thực thi cấu trúc dữ liệu và xác nhận các định dạng và nội dung của dữ liệu. Quy định chạy .validate quy tắc sau khi xác minh rằng một .write quy tắc cấp quyền truy cập.

Các loại quy tắc
.đọc Mô tả nếu và khi nào dữ liệu được phép đọc bởi người dùng.
.viết Mô tả nếu và khi nào dữ liệu được phép ghi.
.validate Xác định giá trị được định dạng đúng sẽ trông như thế nào, cho dù nó có các thuộc tính con và kiểu dữ liệu.

Theo mặc định, nếu không có quy tắc nào cho phép nó, quyền truy cập tại một đường dẫn sẽ bị từ chối.

Điều kiện xây dựng

Cloud Firestore

Điều kiện là một biểu thức boolean xác định xem một hoạt động cụ thể nên được phép hay bị từ chối. Các requestresource biến cung cấp bối cảnh cho những điều kiện này.

Các request biến

Các request biến bao gồm các lĩnh vực sau đây và thông tin tương ứng:

request.auth

Mã thông báo web JSON (JWT) chứa thông tin xác thực từ Xác thực Firebase. auth thẻ chứa một tập hợp các yêu cầu tiêu chuẩn và tùy chỉnh bất kỳ khiếu nại bạn tạo thông qua căn cứ hỏa lực xác thực. Tìm hiểu thêm về căn cứ hỏa lực Rules và xác thực bảo mật .

request.method

Các request.method có thể bất kỳ phương pháp tiêu chuẩn hoặc một phương pháp tùy chỉnh. Các phương pháp thuận tiện readwrite cũng tồn tại để đơn giản hóa văn bản quy tắc áp dụng cho tất cả các phương pháp chỉ đọc hoặc tất cả chỉ ghi tiêu chuẩn tương ứng.

request.params

Các request.params bao gồm bất kỳ dữ liệu không liên quan cụ thể đến request.resource có thể hữu ích để đánh giá. Trên thực tế, bản đồ này phải trống đối với tất cả các phương pháp tiêu chuẩn và phải chứa dữ liệu phi tài nguyên cho các phương pháp tùy chỉnh. Các dịch vụ phải cẩn thận để không đổi tên hoặc sửa đổi loại của bất kỳ khóa và giá trị nào được trình bày dưới dạng tham số.

request.path

Các request.path là đường dẫn cho các mục tiêu resource . Đường dẫn có liên quan đến dịch vụ. Đoạn đường có chứa phi url ký tự an toàn chẳng hạn như / là url-mã hóa.

Các resource biến

Các resource là giá trị hiện tại trong ngành biểu diễn dưới dạng một bản đồ của cặp khóa-giá trị. Tham khảo resource trong một điều kiện sẽ dẫn đến nhiều nhất là một đọc giá trị từ dịch vụ. Việc tra cứu này sẽ được tính vào mọi hạn ngạch liên quan đến dịch vụ cho tài nguyên. Đối với get yêu cầu, resource sẽ chỉ được tính vào hạn ngạch trên từ chối.

Các nhà khai thác và quyền ưu tiên của nhà điều hành

Sử dụng bảng dưới đây làm tài liệu tham khảo cho các toán tử và mức độ ưu tiên tương ứng của chúng trong Quy tắc dành cho Cloud Firestore và Cloud Storage.

Với biểu thức tùy ý ab , một lĩnh vực f , và một chỉ số i .

Nhà điều hành Sự miêu tả Sự liên kết
a[i] a() af Lập chỉ mục, cuộc gọi, truy cập trường trái sang phải
!a -a Phủ định đơn nguyên phải sang trái
a/ba%ba*b Toán tử nhân trái sang phải
a+b ab Toán tử cộng trái sang phải
a>ba>=ba Toán tử quan hệ trái sang phải
a in b Sự tồn tại trong danh sách hoặc bản đồ trái sang phải
a is type Loại so sánh, nơi type có thể bool, int, float, số, chuỗi, danh sách, bản đồ, dấu thời gian, thời gian, đường dẫn hoặc latlng trái sang phải
a==ba!=b Toán tử so sánh trái sang phải
a && b Có điều kiện VÀ trái sang phải
a || b HOẶC có điều kiện trái sang phải
a ? true_value : false_value Biểu thức bậc ba trái sang phải

Lưu trữ đám mây

Điều kiện là một biểu thức boolean xác định xem một hoạt động cụ thể nên được phép hay bị từ chối. Các requestresource biến cung cấp bối cảnh cho những điều kiện này.

Các request biến

Các request biến bao gồm các lĩnh vực sau đây và thông tin tương ứng:

request.auth

Mã thông báo web JSON (JWT) chứa thông tin xác thực từ Xác thực Firebase. auth thẻ chứa một tập hợp các yêu cầu tiêu chuẩn và tùy chỉnh bất kỳ khiếu nại bạn tạo thông qua căn cứ hỏa lực xác thực. Tìm hiểu thêm về căn cứ hỏa lực Rules và xác thực bảo mật .

request.method

Các request.method có thể bất kỳ phương pháp tiêu chuẩn hoặc một phương pháp tùy chỉnh. Các phương pháp thuận tiện readwrite cũng tồn tại để đơn giản hóa văn bản quy tắc áp dụng cho tất cả các phương pháp chỉ đọc hoặc tất cả chỉ ghi tiêu chuẩn tương ứng.

request.params

Các request.params bao gồm bất kỳ dữ liệu không liên quan cụ thể đến request.resource có thể hữu ích để đánh giá. Trên thực tế, bản đồ này phải trống đối với tất cả các phương pháp tiêu chuẩn và phải chứa dữ liệu phi tài nguyên cho các phương pháp tùy chỉnh. Các dịch vụ phải cẩn thận để không đổi tên hoặc sửa đổi loại của bất kỳ khóa và giá trị nào được trình bày dưới dạng tham số.

request.path

Các request.path là đường dẫn cho các mục tiêu resource . Đường dẫn có liên quan đến dịch vụ. Đoạn đường có chứa phi url ký tự an toàn chẳng hạn như / là url-mã hóa.

Các resource biến

Các resource là giá trị hiện tại trong ngành biểu diễn dưới dạng một bản đồ của cặp khóa-giá trị. Tham khảo resource trong một điều kiện sẽ dẫn đến nhiều nhất là một đọc giá trị từ dịch vụ. Việc tra cứu này sẽ được tính vào mọi hạn ngạch liên quan đến dịch vụ cho tài nguyên. Đối với get yêu cầu, resource sẽ chỉ được tính vào hạn ngạch trên từ chối.

Các nhà khai thác và quyền ưu tiên của nhà điều hành

Sử dụng bảng bên dưới làm tài liệu tham khảo cho các toán tử và mức độ ưu tiên tương ứng của chúng trong Quy tắc dành cho Cloud Firestore và Cloud Storage.

Với biểu thức tùy ý ab , một lĩnh vực f , và một chỉ số i .

Nhà điều hành Sự miêu tả Sự liên kết
a[i] a() af Lập chỉ mục, cuộc gọi, truy cập trường trái sang phải
!a -a Phủ định đơn nguyên phải sang trái
a/ba%ba*b Toán tử nhân trái sang phải
a+b ab Toán tử cộng trái sang phải
a>ba>=ba Toán tử quan hệ trái sang phải
a in b Sự tồn tại trong danh sách hoặc bản đồ trái sang phải
a is type Loại so sánh, nơi type có thể bool, int, float, số, chuỗi, danh sách, bản đồ, dấu thời gian, thời gian, đường dẫn hoặc latlng trái sang phải
a==ba!=b Toán tử so sánh trái sang phải
a && b Có điều kiện VÀ trái sang phải
a || b HOẶC có điều kiện trái sang phải
a ? true_value : false_value Biểu thức bậc ba trái sang phải

Cơ sở dữ liệu thời gian thực

Điều kiện là một biểu thức boolean xác định liệu một hoạt động cụ thể nên được phép hay bị từ chối. Bạn có thể xác định các điều kiện đó trong Quy tắc cơ sở dữ liệu thời gian thực theo những cách sau.

Các biến được xác định trước

Có một số biến hữu ích, được xác định trước có thể được truy cập bên trong định nghĩa quy tắc. Dưới đây là một bản tóm tắt ngắn gọn về từng loại:

Các biến được xác định trước
hiện nay Thời gian hiện tại tính bằng mili giây kể từ kỷ nguyên Linux. Điều này đặc biệt hiệu quả để xác thực dấu thời gian được tạo bằng firebase.database.ServerValue.TIMESTAMP của SDK.
nguồn gốc Một RuleDataSnapshot đại diện cho đường dẫn gốc trong cơ sở dữ liệu căn cứ hỏa lực như nó tồn tại trước khi phẫu thuật đã cố gắng.
dữ liệu mới Một RuleDataSnapshot đại diện cho dữ liệu vì nó sẽ tồn tại sau ca phẫu thuật đã cố gắng. Nó bao gồm dữ liệu mới đang được ghi và dữ liệu hiện có.
dữ liệu Một RuleDataSnapshot đại diện cho dữ liệu vì nó đã tồn tại trước khi phẫu thuật đã cố gắng.
$ biến Một đường dẫn ký tự đại diện được sử dụng để đại diện cho id và khóa con động.
auth Đại diện cho khối lượng mã thông báo của người dùng đã được xác thực.

Các biến này có thể được sử dụng ở bất kỳ đâu trong quy tắc của bạn. Ví dụ, các quy tắc bảo mật dưới đây đảm bảo rằng dữ liệu được ghi vào /foo/ nút phải là một chuỗi ít hơn 100 ký tự:

{
  "rules": {
    "foo": {
      // /foo is readable by the world
      ".read": true,

      // /foo is writable by the world
      ".write": true,

      // data written to /foo must be a string less than 100 characters
      ".validate": "newData.isString() && newData.val().length < 100"
    }
  }
}

Quy tắc dựa trên dữ liệu

Bất kỳ dữ liệu nào trong cơ sở dữ liệu của bạn đều có thể được sử dụng trong các quy tắc của bạn. Sử dụng các biến xác định trước root , data , và newData , bạn có thể truy cập vào bất kỳ đường dẫn vì nó sẽ tồn tại trước hoặc sau một sự kiện ghi.

Hãy xem xét ví dụ này, cho phép hoạt động ghi chừng nào giá trị của /allow_writes/ nút là true , node cha không có một readOnly cờ thiết lập, và có một đứa trẻ có tên foo trong các dữ liệu mới bằng văn bản:

".write": "root.child('allow_writes').val() === true &&
          !data.parent().child('readOnly').exists() &&
          newData.child('foo').exists()"

Quy tắc dựa trên truy vấn

Mặc dù bạn không thể sử dụng quy tắc làm bộ lọc, nhưng bạn có thể giới hạn quyền truy cập vào các tập hợp con dữ liệu bằng cách sử dụng các tham số truy vấn trong quy tắc của mình. Sử dụng query. các biểu thức trong quy tắc của bạn để cấp quyền truy cập đọc hoặc ghi dựa trên các tham số truy vấn.

Ví dụ, các quy tắc dựa trên truy vấn sau đây sử dụng quy tắc bảo mật dựa trên người dùng và các quy tắc truy vấn dựa trên để hạn chế quyền truy cập vào dữ liệu trong baskets bộ sưu tập để chỉ các giỏ mua sắm người dùng hoạt động sở hữu:

"baskets": {
  ".read": "auth.uid != null &&
            query.orderByChild == 'owner' &&
            query.equalTo == auth.uid" // restrict basket access to owner of basket
}

Truy vấn sau, bao gồm các tham số truy vấn trong quy tắc, sẽ thành công:

db.ref("baskets").orderByChild("owner")
                 .equalTo(auth.currentUser.uid)
                 .on("value", cb)                 // Would succeed

Tuy nhiên, các truy vấn mà không bao gồm các thông số trong quy tắc sẽ thất bại với một PermissionDenied lỗi:

db.ref("baskets").on("value", cb)                 // Would fail with PermissionDenied

Bạn cũng có thể sử dụng các quy tắc dựa trên truy vấn để giới hạn lượng dữ liệu khách hàng tải xuống thông qua các thao tác đọc.

Ví dụ: quy tắc sau đây giới hạn quyền đọc chỉ đối với 1000 kết quả đầu tiên của truy vấn, được sắp xếp theo mức độ ưu tiên:

messages: {
  ".read": "query.orderByKey &&
            query.limitToFirst <= 1000"
}

// Example queries:

db.ref("messages").on("value", cb)                // Would fail with PermissionDenied

db.ref("messages").limitToFirst(1000)
                  .on("value", cb)                // Would succeed (default order by key)

Sau đây query. biểu thức có sẵn trong Quy tắc cơ sở dữ liệu thời gian thực.

Biểu thức quy tắc dựa trên truy vấn
Biểu hiện Kiểu Sự miêu tả
query.orderByKey
query.orderByPosystem
query.orderByValue
boolean Đúng cho các truy vấn được sắp xếp theo khóa, mức độ ưu tiên hoặc giá trị. Sai khác.
query.orderByChild dây
vô giá trị
Sử dụng một chuỗi để biểu diễn đường dẫn tương đối đến một nút con. Ví dụ, query.orderByChild == "address/zip" . Nếu truy vấn không được sắp xếp bởi một nút con, giá trị này là null.
query.startAt
query.endAt
query.equalTo
dây
con số
boolean
vô giá trị
Truy xuất các giới hạn của truy vấn đang thực thi hoặc trả về null nếu không có tập hợp giới hạn nào.
query.limitToFirst
query.limitToLast
con số
vô giá trị
Lấy giới hạn trên truy vấn đang thực thi hoặc trả về null nếu không có giới hạn nào được đặt.

Các nhà khai thác

Realtime Quy định cơ sở dữ liệu hỗ trợ một số nhà khai thác có thể sử dụng để kết hợp các biến trong báo cáo kết quả tình trạng. Xem danh sách đầy đủ của các nhà khai thác trong tài liệu tham khảo .

Tạo điều kiện

Các điều kiện thực tế của bạn sẽ thay đổi dựa trên quyền truy cập mà bạn muốn cấp. Các quy tắc cố ý cung cấp một mức độ linh hoạt lớn, vì vậy các quy tắc của ứng dụng của bạn cuối cùng có thể đơn giản hoặc phức tạp tùy theo nhu cầu của bạn.

Đối với một số hướng dẫn tạo đơn giản, quy trình sản xuất sẵn sàng, xem Quy định bảo mật cơ bản .