Google cam kết thúc đẩy công bằng chủng tộc cho Cộng đồng người da đen. Xem cách thực hiện.
Trang này được dịch bởi Cloud Translation API.
Switch to English

Kiểm tra Quy tắc bảo mật Cloud Firestore của bạn

Khi đang xây dựng ứng dụng của mình, bạn có thể muốn khóa quyền truy cập vào cơ sở dữ liệu Cloud Firestore của mình. Tuy nhiên, trước khi khởi chạy, bạn sẽ cần Quy tắc bảo mật Cloud Firestore nhiều sắc thái hơn. Với trình giả lập Cloud Firestore, bạn có thể viết các bài kiểm tra đơn vị để kiểm tra hoạt động của Quy tắc bảo mật Cloud Firestore của bạn.

Bắt đầu nhanh

Đối với một số trường hợp thử nghiệm cơ bản với các quy tắc đơn giản, hãy thử bắt đầu nhanh JavaScript hoặc khởi động nhanh TypeScript .

Hiểu các quy tắc bảo mật Cloud Firestore

Triển khai Xác thực FirebaseQuy tắc bảo mật Cloud Firestore để xác thực không máy chủ, ủy quyền và xác thực dữ liệu khi bạn sử dụng thư viện ứng dụng khách di động và web.

Quy tắc bảo mật Cloud Firestore bao gồm hai phần:

  1. Câu lệnh so match xác định các tài liệu trong cơ sở dữ liệu của bạn.
  2. Biểu thức allow kiểm soát quyền truy cập vào các tài liệu đó.

Xác thực Firebase xác minh thông tin đăng nhập của người dùng và cung cấp nền tảng cho các hệ thống truy cập dựa trên vai trò và người dùng.

Mọi yêu cầu cơ sở dữ liệu từ thư viện máy khách web / di động Cloud Firestore đều được đánh giá dựa trên các quy tắc bảo mật của bạn trước khi đọc hoặc ghi bất kỳ dữ liệu nào. Nếu các quy tắc từ chối quyền truy cập vào bất kỳ đường dẫn tài liệu nào được chỉ định, thì toàn bộ yêu cầu sẽ không thành công.

Tìm hiểu thêm về Quy tắc bảo mật Cloud Firestore trong Bắt đầu với Quy tắc bảo mật Cloud Firestore .

Cài đặt trình giả lập

Để cài đặt trình giả lập Cloud Firestore, hãy sử dụng Firebase CLI và chạy lệnh bên dưới:

firebase setup:emulators:firestore

Chạy trình giả lập

Khởi động trình giả lập bằng lệnh sau. Trình giả lập sẽ chạy cho đến khi bạn kết thúc quá trình:

firebase emulators:start --only firestore

Trong nhiều trường hợp, bạn muốn khởi động trình giả lập, hãy chạy bộ thử nghiệm, sau đó tắt trình giả lập sau khi chạy thử nghiệm. Bạn có thể làm điều này một cách dễ dàng bằng cách sử dụng emulators:exec lệnh emulators:exec :

firebase emulators:exec --only firestore "./my-test-script.sh"

Khi khởi động, trình giả lập sẽ cố gắng chạy trên một cổng mặc định (8080). Bạn có thể thay đổi cổng trình giả lập bằng cách sửa đổi phần "emulators" trong tệp firebase.json của mình:

{
  // ...
  "emulators": {
    "firestore": {
      "port": "YOUR_PORT"
    }
  }
}

Trước khi bạn chạy trình giả lập

Trước khi bạn bắt đầu sử dụng trình giả lập, hãy ghi nhớ những điều sau:

  • Trình mô phỏng ban đầu sẽ tải các quy tắc được chỉ định trong trường firestore.rules của tệp firebase.json của bạn. Nó yêu cầu tên của một tệp cục bộ chứa Quy tắc bảo mật Cloud Firestore của bạn và áp dụng các quy tắc đó cho tất cả các dự án. Nếu bạn không cung cấp đường dẫn tệp cục bộ hoặc sử dụng phương thức loadFirestoreRules như được mô tả bên dưới, trình giả lập coi tất cả các dự án là có quy tắc mở.
  • Mặc dù hầu hết các SDK Firebase đều hoạt động trực tiếp với trình giả lập, nhưng chỉ thư viện @firebase/rules-unit-testing hỗ trợ mocking auth trong Quy tắc bảo mật, giúp kiểm tra đơn vị dễ dàng hơn nhiều. Ngoài ra, thư viện hỗ trợ một số tính năng dành riêng cho trình giả lập như xóa tất cả dữ liệu, như được liệt kê bên dưới.
  • Trình giả lập cũng sẽ chấp nhận mã thông báo Firebase Auth sản xuất được cung cấp thông qua SDK khách hàng và đánh giá các quy tắc cho phù hợp, cho phép kết nối ứng dụng của bạn trực tiếp với trình giả lập trong quá trình tích hợp và kiểm tra thủ công.

Chạy thử nghiệm cục bộ

initializeTestApp({ projectId: string, auth: Object }) => FirebaseApp

Phương thức này trả về ứng dụng Firebase đã khởi tạo tương ứng với ID dự án và biến xác thực được chỉ định trong các tùy chọn. Sử dụng quyền này để tạo một ứng dụng được xác thực là một người dùng cụ thể để sử dụng trong các thử nghiệm.

firebase.initializeTestApp({
  projectId: "my-test-project",
  auth: { uid: "alice", email: "alice@example.com" }
});

initializeAdminApp({ projectId: string }) => FirebaseApp

Phương thức này trả về ứng dụng Firebase quản trị viên đã khởi tạo. Ứng dụng này bỏ qua các quy tắc bảo mật khi thực hiện đọc và ghi. Sử dụng quyền này để tạo ứng dụng được xác thực với tư cách quản trị viên để đặt trạng thái cho các thử nghiệm.

firebase.initializeAdminApp({ projectId: "my-test-project" });
    

apps() => [FirebaseApp] Phương thức này trả về tất cả các ứng dụng quản trị và thử nghiệm hiện được khởi tạo. Sử dụng công cụ này để dọn dẹp ứng dụng giữa hoặc sau khi kiểm tra.

Promise.all(firebase.apps().map(app => app.delete()))

loadFirestoreRules({ projectId: string, rules: Object }) => Promise

Phương thức này gửi các quy tắc đến một cơ sở dữ liệu đang chạy cục bộ. Nó nhận một đối tượng xác định các quy tắc dưới dạng một chuỗi. Sử dụng phương pháp này để thiết lập các quy tắc cho cơ sở dữ liệu của bạn.

firebase.loadFirestoreRules({
  projectId: "my-test-project",
  rules: fs.readFileSync("/path/to/firestore.rules", "utf8")
});
    

assertFails(pr: Promise) => Promise

Phương thức này trả về một lời hứa bị từ chối nếu đầu vào thành công hoặc thành công nếu đầu vào bị từ chối. Sử dụng điều này để xác nhận nếu một cơ sở dữ liệu đọc hoặc ghi không thành công.

firebase.assertFails(app.firestore().collection("private").doc("super-secret-document").get());
    

assertSucceeds(pr: Promise) => Promise

Phương thức này trả về một lời hứa thành công nếu đầu vào thành công và bị từ chối nếu đầu vào bị từ chối. Sử dụng điều này để xác nhận nếu một cơ sở dữ liệu đọc hoặc ghi thành công.

firebase.assertSucceeds(app.firestore().collection("public").doc("test-document").get());
    

clearFirestoreData({ projectId: string }) => Promise

Phương pháp này xóa tất cả dữ liệu liên quan đến một dự án cụ thể trong phiên bản Firestore đang chạy cục bộ. Sử dụng phương pháp này để làm sạch sau khi kiểm tra.

firebase.clearFirestoreData({
  projectId: "my-test-project"
});
   

Tạo báo cáo thử nghiệm

Sau khi chạy một bộ kiểm tra, bạn có thể truy cập các báo cáo phạm vi kiểm tra cho biết từng quy tắc bảo mật của bạn được đánh giá như thế nào.

Để nhận báo cáo, hãy truy vấn một điểm cuối được tiếp xúc trên trình giả lập khi nó đang chạy. Đối với phiên bản thân thiện với trình duyệt, hãy sử dụng URL sau:

http://localhost:8080/emulator/v1/projects/<project_id>:ruleCoverage.html

Điều này phá vỡ các quy tắc của bạn thành các biểu thức và biểu thức con mà bạn có thể di chuột qua để biết thêm thông tin, bao gồm số lượng đánh giá và giá trị được trả về. Đối với phiên bản JSON thô của dữ liệu này, hãy bao gồm URL sau trong truy vấn của bạn:

http://localhost:8080/emulator/v1/projects/<project_id>:ruleCoverage

Sự khác biệt giữa trình giả lập và sản xuất

  1. Bạn không phải tạo dự án Cloud Firestore một cách rõ ràng. Trình giả lập tự động tạo bất kỳ phiên bản nào được truy cập.
  2. Trình giả lập Cloud Firestore không hoạt động với quy trình Xác thực Firebase thông thường. Thay vào đó, trong SDK kiểm tra Firebase, chúng tôi đã cung cấp phương thức initializeTestApp() trong thư viện rules-unit-testing , sử dụng trường auth . Tay cầm Firebase được tạo bằng phương pháp này sẽ hoạt động như thể nó đã được xác thực thành công dưới dạng bất kỳ thực thể nào bạn cung cấp. Nếu bạn chuyển bằng null , nó sẽ hoạt động như một người dùng chưa được xác thực (ví dụ: quy tắc auth != null sẽ không thành công).

Khắc phục sự cố đã biết

Khi sử dụng trình giả lập Cloud Firestore, bạn có thể gặp phải các sự cố đã biết sau. Làm theo hướng dẫn bên dưới để khắc phục mọi hành vi bất thường mà bạn đang gặp phải. Các ghi chú này được viết với SDK kiểm tra Firebase, nhưng các phương pháp chung có thể áp dụng cho mọi SDK Firebase.

Hành vi kiểm tra không nhất quán

Nếu các bài kiểm tra của bạn thỉnh thoảng đạt và không đạt, ngay cả khi không có bất kỳ thay đổi nào đối với các bài kiểm tra, bạn có thể cần xác minh rằng chúng được trình tự đúng. Hầu hết các tương tác với trình giả lập là không đồng bộ, vì vậy hãy kiểm tra kỹ xem tất cả mã không đồng bộ có được sắp xếp đúng trình tự hay không. Bạn có thể sửa trình tự bằng cách xâu chuỗi lời hứa hoặc sử dụng ký hiệu await một cách tự do.

Đặc biệt, hãy xem lại các hoạt động không đồng bộ sau:

  • Đặt quy tắc bảo mật, chẳng hạn như firebase.loadFirestoreRules .
  • Đọc và ghi dữ liệu, ví dụ: với db.collection("users").doc("alice").get() .
  • Xác nhận hoạt động, bao gồm firebase.assertSucceedsfirebase.assertFails .

Kiểm tra chỉ vượt qua lần đầu tiên bạn tải trình giả lập

Trình giả lập là trạng thái. Nó lưu trữ tất cả dữ liệu được ghi vào bộ nhớ, vì vậy mọi dữ liệu sẽ bị mất bất cứ khi nào trình giả lập tắt. Nếu bạn đang chạy nhiều thử nghiệm với cùng một id dự án, mỗi thử nghiệm có thể tạo ra dữ liệu có thể ảnh hưởng đến các thử nghiệm tiếp theo. Bạn có thể sử dụng bất kỳ phương pháp nào sau đây để bỏ qua hành vi này:

  • Sử dụng các ID dự án duy nhất cho mỗi thử nghiệm. Lưu ý rằng nếu bạn chọn làm điều này, bạn sẽ cần gọi loadFirestoreRules như một phần của mỗi bài kiểm tra; quy tắc chỉ được tải tự động cho ID dự án mặc định.
  • Cấu trúc lại các bài kiểm tra của bạn để chúng không tương tác với dữ liệu đã viết trước đó (ví dụ: sử dụng một bộ sưu tập khác nhau cho mỗi bài kiểm tra).
  • Xóa tất cả dữ liệu được ghi trong quá trình kiểm tra.

Thiết lập kiểm tra rất phức tạp

Bạn có thể muốn kiểm tra các tình huống mà Quy tắc bảo mật Cloud Firestore của bạn không thực sự cho phép. Ví dụ: khó kiểm tra xem người dùng chưa được xác thực có thể chỉnh sửa dữ liệu hay không, vì bạn không thể chỉnh sửa dữ liệu với tư cách là người dùng chưa được xác thực.

Nếu các quy tắc của bạn làm cho việc thiết lập thử nghiệm trở nên phức tạp, hãy thử sử dụng ứng dụng khách được quản trị viên ủy quyền để bỏ qua các quy tắc. Bạn có thể làm điều này với firebase.initializeAdminApp . Đọc và ghi từ máy khách được quản trị viên ủy quyền bỏ qua các quy tắc và không kích hoạt lỗi PERMISSION_DENIED .