Trang này được dịch bởi Cloud Translation API.
Switch to English

Bảo mật dựa trên người dùng

Tài liệu này đã xem lại khái niệm từ Securing dữ liệu của bạn , kết hợp được xác định trước auth biến để tạo ra một giải pháp hoàn chỉnh cho việc đảm bảo dữ liệu của chúng tôi.

Tích hợp xác thực

Xác thực Firebase tích hợp với Cơ sở dữ liệu thời gian thực Firebase để cho phép bạn kiểm soát truy cập dữ liệu trên cơ sở mỗi người dùng.

Khi người dùng xác thực, biến auth trong quy tắc Quy tắc cơ sở dữ liệu thời gian thực của bạn sẽ được điền với thông tin của người dùng. Thông tin này bao gồm số nhận dạng duy nhất của họ ( uid ) cũng như dữ liệu tài khoản được liên kết, chẳng hạn như id Facebook hoặc địa chỉ email và thông tin khác. Nếu bạn triển khai nhà cung cấp xác thực tùy chỉnh, bạn có thể thêm các trường của riêng mình vào tải trọng xác thực của người dùng.

Hướng dẫn này giải thích cách kết hợp ngôn ngữ Quy tắc cơ sở dữ liệu thời gian thực Firebase với thông tin xác thực về người dùng của bạn. Bằng cách kết hợp hai khái niệm này, 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.

Biến auth

Biến auth được xác định trước trong các quy tắc là null trước khi xác thực diễn ra. Khi người dùng được xác thực bằng Xác thực Firebase , nó sẽ chứa các thuộc tính sau:

các nhà cung cấp Phương thức xác thực được sử dụng ("mật khẩu", "ẩn danh", "facebook", "github", "google" hoặc "twitter").
uid Id người dùng duy nhất, được đảm bảo là duy nhất trên tất cả các nhà cung cấp.
mã thông báo Nội dung của mã thông báo ID xác thực Firebase. Xem tài liệu tham khảo cho auth.token để biết thêm chi tiết.

Dưới đây là một quy tắc ví dụ sử dụng biến auth để đảm bảo rằng mỗi người dùng chỉ có thể ghi vào một đường dẫn cụ thể của người dùng:

{
  "rules": {
    "users": {
      "$user_id": {
        // grants write access to the owner of this user account
        // whose uid must exactly match the key ($user_id)
        ".write": "$user_id === auth.uid"
      }
    }
  }
}

Cấu trúc cơ sở dữ liệu của bạn

Đôi khi rất hữu ích khi cấu trúc cơ sở dữ liệu của bạn theo cách làm cho việc viết các quy tắc bảo mật dễ dàng hơn. Ví dụ, một mẫu phổ biến để lưu trữ dữ liệu người dùng trong Cơ sở dữ liệu thời gian thực là lưu trữ tất cả người dùng của bạn trong một nút users duy nhất có con là giá trị uid cho mỗi người dùng. Nếu bạn muốn hạn chế quyền truy cập vào dữ liệu này để chỉ người dùng đã đăng nhập mới có thể xem dữ liệu của họ, quy tắc của bạn sẽ trông giống như thế này:

{
  "rules": {
    "users": {
      "$uid": {
        ".read": "auth != null && auth.uid == $uid"
      }
    }
  }
}

Làm việc với xác nhận tùy chỉnh xác thực

Đối với các ứng dụng yêu cầu kiểm soát truy cập tùy chỉnh cho những người dùng khác nhau, Xác thực Firebase cho phép nhà phát triển đặt khiếu nại cho người dùng Firebase . Những tuyên bố này là auth.token trong biến auth.token trong quy tắc của bạn. Dưới đây là một ví dụ về các quy tắc sử dụng khiếu nại tùy chỉnh hasEmergencyTowel :

{
  "rules": {
    "frood": {
      // A towel is about the most massively useful thing an interstellar
      // hitchhiker can have
      ".read": "auth.token.hasEmergencyTowel === true"
    }
  }
}

Các nhà phát triển tạo mã thông báo xác thực tùy chỉnh của riêng họ có thể tùy chọn thêm khiếu nại vào các mã thông báo này. Những khiếu nại này có sẵn trên biến auth.token trong quy tắc của bạn.

Xem lại ví dụ trò chuyện

Hãy xây dựng ví dụ trò chuyện từ Bảo mật dữ liệu của bạn và thêm một số xác thực người dùng, kéo tất cả các khái niệm này lại với nhau thành một ứng dụng hoạt động:

{
  "rules": {
    "room_names": {
      // any logged in user can get a list of room names
      ".read": "auth !== null",

      "$room_id": {
        // this is just for documenting the structure of rooms, since
        // they are read-only and no write rule allows this to be set
        ".validate": "newData.isString()"
      }
    },

    "members": {
       // I can join or leave any room (otherwise it would be a boring demo)
       // I can have a different name in each room just for fun
       "$room_id": {
          // any member can read the list of member names
          ".read": "data.child(auth.uid).exists()",

          // room must already exist to add a member
          ".validate": "root.child('room_names/'+$room_id).exists()",

          "$user_id": {
             ".write": "auth.uid === $user_id",
             ".validate": "newData.isString() && newData.val().length > 0 && newData.val().length < 20"
          }
       }
    },

    "messages": {
      "$room_id": {
        // the list of messages for a room can be read by any member
        ".read": "root.child('members/'+$room_id+'/'+auth.uid).exists()",

        // room we want to write a message to must be valid
        ".validate": "root.child('room_names/'+$room_id).exists()",

        "$message_id": {
          // a new message can be created if it does not exist, but it
          // cannot be modified or deleted
          // any member of a room can write a new message
          ".write": "root.child('members/'+$room_id+'/'+auth.uid).exists() && !data.exists() && newData.exists()",

          // the room attribute must be a valid key in room_names/ (the room must exist)
          // the object to write must have a name, message, and timestamp
          ".validate": "newData.hasChildren(['user', 'message', 'timestamp'])",

          // the message must be written by logged in user
          "user": {
             ".validate": "newData.val() === auth.uid"
          },

          // the message must be longer than 0 chars and less than 50
          "message": { ".validate": "newData.isString() && newData.val().length > 0 && newData.val().length < 50" },

          // messages cannot be added in the past or the future
          // clients should use firebase.database.ServerValue.TIMESTAMP
          // to ensure accurate timestamps
          "timestamp": { ".validate": "newData.val() <= now" },

          // no other fields can be included in a message
          "$other": { ".validate": false }
        }
      }
    }
  }
}

Bước tiếp theo