Firebase Security Rules cung cấp tính năng kiểm soát quyền truy cập và xác thực dữ liệu ở định dạng hỗ trợ nhiều cấp độ phức tạp. Để xây dựng hệ thống quyền truy cập dựa trên người dùng và vai trò giúp bảo vệ dữ liệu của người dùng, hãy sử dụng Firebase Authentication với Firebase Security Rules.
Xác định người dùng
Authentication xác định những người dùng yêu cầu quyền truy cập vào dữ liệu của bạn và cung cấp thông tin đó dưới dạng một biến mà bạn có thể tận dụng trong các quy tắc của mình. Biến auth
chứa các thông tin sau:
uid
: Mã nhận dạng người dùng duy nhất, được chỉ định cho người dùng yêu cầu.token
: Bản đồ các giá trị do Authentication thu thập.
Biến auth.token
chứa các giá trị sau:
Trường | Mô tả |
---|---|
email |
Địa chỉ email liên kết với tài khoản, nếu có. |
email_verified |
true nếu người dùng đã xác minh rằng họ có quyền truy cập vào địa chỉ email . Một số nhà cung cấp tự động xác minh địa chỉ email mà họ sở hữu. |
phone_number |
Số điện thoại được liên kết với tài khoản (nếu có). |
name |
Tên hiển thị của người dùng, nếu được đặt. |
sub |
UID Firebase của người dùng. Đây là giá trị duy nhất trong một dự án. |
firebase.identities |
Từ điển của tất cả danh tính được liên kết với tài khoản của người dùng này. Các khoá của từ điển có thể là bất kỳ khoá nào sau đây: email , phone , google.com , facebook.com , github.com , twitter.com . Các giá trị của từ điển là các mảng gồm giá trị nhận dạng duy nhất cho từng nhà cung cấp danh tính được liên kết với tài khoản. Ví dụ: auth.token.firebase.identities["google.com"][0] chứa mã nhận dạng người dùng Google đầu tiên được liên kết với tài khoản. |
firebase.sign_in_provider |
Nhà cung cấp dịch vụ đăng nhập dùng để lấy mã thông báo này. Có thể là một trong các chuỗi sau: custom , password , phone , anonymous , google.com , facebook.com , github.com , twitter.com . |
firebase.tenant |
tenantId được liên kết với tài khoản, nếu có. Ví dụ: tenant2-m6tyz |
Nếu bạn muốn thêm các thuộc tính xác thực tuỳ chỉnh, biến auth.token
cũng chứa mọi câu nhận định tuỳ chỉnh mà bạn chỉ định.
Khi người dùng yêu cầu quyền truy cập chưa đăng nhập, biến auth
sẽ là null
.
Bạn có thể tận dụng điều này trong các quy tắc của mình nếu muốn giới hạn quyền đọc cho những người dùng đã xác thực — auth != null
. Tuy nhiên, bạn nên hạn chế quyền ghi hơn nữa.
Để biết thêm thông tin về biến auth
, hãy xem tài liệu tham khảo cho Cloud Firestore, Realtime Database và Cloud Storage.
Tận dụng thông tin người dùng trong các quy tắc
Trong thực tế, việc sử dụng thông tin đã xác thực trong quy tắc sẽ giúp quy tắc của bạn mạnh mẽ và linh hoạt hơn. Bạn có thể kiểm soát quyền truy cập vào dữ liệu dựa trên danh tính người dùng.
Trong các quy tắc của bạn, hãy xác định cách thông tin trong biến auth
(thông tin người dùng của người yêu cầu) khớp với thông tin người dùng liên kết với dữ liệu được yêu cầu.
Ví dụ: ứng dụng của bạn có thể muốn đảm bảo người dùng chỉ có thể đọc và ghi dữ liệu của riêng họ. Trong trường hợp này, bạn muốn có sự trùng khớp giữa biến auth.uid
và mã nhận dạng người dùng trên dữ liệu được yêu cầu:
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
// Make sure the uid of the requesting user matches name of the user
// document. The wildcard expression {userId} makes the userId variable
// available in rules.
match /users/{userId} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
}
}
Realtime Database
{
"rules": {
"users": {
"$userId": {
// grants write access to the owner of this user account
// whose uid must exactly match the key ($userId)
".write": "$userId === auth.uid"
}
}
}
}
Cloud Storage
service firebase.storage {
// Only a user can upload their file, but anyone can view it
match /users/{userId}/{fileName} {
allow read;
allow write: if request.auth != null && request.auth.uid == userId;
}
}
Xác định thông tin tuỳ chỉnh của người dùng
Bạn có thể tận dụng thêm biến auth
để xác định các trường tuỳ chỉnh được chỉ định cho người dùng của ứng dụng.
Ví dụ: giả sử bạn muốn tạo vai trò "quản trị viên" cho phép quyền ghi trên một số đường dẫn nhất định. Bạn sẽ chỉ định thuộc tính đó cho người dùng, sau đó tận dụng thuộc tính đó trong các quy tắc cấp quyền truy cập trên các đường dẫn.
Trong Cloud Firestore, bạn có thể thêm một trường tuỳ chỉnh vào tài liệu của người dùng và truy xuất giá trị của trường đó bằng một hoạt động đọc được nhúng trong quy tắc. Vì vậy, quy tắc dựa trên quản trị viên của bạn sẽ có dạng như ví dụ sau:
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents/some_collection: {
// Remember that, in Cloud Firestore, reads embedded in your rules are billed operations
write: if request.auth != null && get(/databases/(database)/documents/users/$(request.auth.uid)).data.admin == true;
read: if request.auth != null;
}
}
Bạn có thể truy cập vào thông báo xác nhận quyền sở hữu tuỳ chỉnh trong Rules sau khi tạo thông báo xác nhận quyền sở hữu tuỳ chỉnh trong Authentication. Sau đó, bạn có thể tham chiếu các tuyên bố tuỳ chỉnh đó bằng biến auth.token
.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
// For attribute-based access control, check for an admin claim
allow write: if request.auth.token.admin == true;
allow read: true;
// Alterntatively, for role-based access, assign specific roles to users
match /some_collection/{document} {
allow read: if request.auth.token.reader == "true";
allow write: if request.auth.token.writer == "true";
}
}
}
Realtime Database
{
"rules": {
"some_path/$sub_path": {
// Create a custom claim for the admin role
".write": "auth.uid !== null && auth.token.writer === true"
".read": "auth.uid !== null"
}
}
}
Cloud Storage
service firebase.storage {
// Create a custom claim for the admin role
match /files/{fileName} {
allow read: if request.auth.uid != null;
allow write: if request.auth.token.admin == true;
}
}
Để xem thêm ví dụ về cách Rules cơ bản sử dụng Authentication, hãy xem bài viết Quy tắc bảo mật cơ bản.