Quy tắc bảo mật và phương pháp xác thực Firebase

Firebase Security Rules cung cấp chức 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 mức độ phức tạp. Để xây dựng hệ thống truy cập dựa trên người dùng và dựa trên vai trò giúp người dùng an toàn dữ liệu, 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 rằng làm 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 được 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ó).
sub UID trên Firebase của người dùng. Đây là giá trị duy nhất trong một dự án.
firebase.identities Từ điển về tất cả danh tính liên kết với tài khoản của người dùng này. 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. Giá trị của từ điển là các mảng mã 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 Mã người thuê đượ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 thuộc tính xác thực tuỳ chỉnh, auth.token biến cũng chứa mọi thông báo xác nhận quyền sở hữu tuỳ chỉnh mà bạn chỉ định.

Khi người dùng yêu cầu quyền truy cập họ không đă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 bạn muốn giới hạn việc đọc quyền truy cập vào người dùng đã xác thực – auth != null. Tuy nhiên, bạn nên sẽ hạn chế thêm quyền ghi.

Để biết thêm thông tin về biến auth, hãy xem tài liệu tham khảo tài liệu cho Cloud Firestore, Realtime DatabaseCloud 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 được xác thực trong các 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 nhận dạng.

Trong các quy tắc, hãy xác định cách thông tin trong biến auth — phần 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 được liên kết với dữ liệu được yêu cầu.

Ví dụ: ứng dụng của bạn nên đảm bảo rằng người dùng chỉ có thể đọc và ghi dữ liệu dữ liệu của riêng bạn. Trong trường hợp này, bạn muốn có kết quả 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 người dùng tuỳ chỉnh

Bạn có thể tận dụng thêm biến auth để xác định các trường tuỳ chỉnh đã chỉ định cho người dùng ứng dụng của bạn.

Ví dụ: giả sử bạn muốn tạo một "quản trị viên" vai trò cho phép truy cập ghi trên các đường dẫn nhất định. Bạn sẽ chỉ định thuộc tính đó cho người dùng và sau đó tận dụng nó 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 trường tuỳ chỉnh vào tài liệu và truy xuất giá trị của trường đó với lượt đọc được nhúng trong quy tắc của bạn. Vì vậy, dựa trên quyền truy cập của quản trị viên, quy tắc 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ể sử dụng các 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 đến các thông báo xác nhận quyền sở hữu tuỳ chỉnh đó bằng cách sử dụ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 Quy tắc bảo mật cơ bản.