Firebase: approach to storing room passwords

2019-07-30 03:01发布

I'm building a web application with Firebase and Angular5. I want to make possible to create/join private rooms (protected by password).

Currently I am at the stage of designing the database and can't really see how I can check user entering the correct room password without actually retrieving it from the firebase database (thus making it completely insecure).

Should I employ cloud functions for that matter. Or can it be done directly with firebase and I'm missing something?

2条回答
祖国的老花朵
2楼-- · 2019-07-30 03:43

You can do this in firebase.

Suppose part of your DB is laid out like :

/chatRooms/$roomID/password = $PASSWORD

Read/write permission to /chatRooms/$roomID/password is granted to the chatroom owner.

To become a member of a chatroom, you must add a document to: chatRooms/$roomId/users/$userId with the following validation:

The entry's userId must be the current user, and the password field must equal the password. A verification rule can access ANY data in the database, even if the user cannot access the data.

Below is an (untested) example that will show the basic principles.

In short:

  1. only the chatroom admin may set the password. No one may read it.
  2. chat data can be read by a user if their uid is in the members collection
  3. to add a member to the collection, they must write a password, equal to (at the time) the room password

code:

"chatrooms" : {      
  "$room_id" : {
    "chat data" : {
      ".read" : "root.child('/chattrooms/' + $room_id + '/members/' + auth.uid).exists()"
    }, 
    "password": {
      ".read": "false",
      ".write": "root.child('/chattrooms/' + $room_id).child('admin').val() == auth.uid"
    }, 
    "members" : {
      "$user_id" : {
        ".validate": "$user_id == auth.uid && newData.val() == root.child('/chattrooms/' + $room_id + '/password').val()"
      }
    }
  }
}
查看更多
女痞
3楼-- · 2019-07-30 03:45

One way to do this that doesn't require a server is by embedding the password into the path of the room. For example: if you have a room "general" and password "correcthorsebatterystaple", then you could model this as:

messages
    general_correcthorsebatterystaple
roomnames
    general

And secure it with:

{
  rules: {
    messages: {
      "$roomid": {
        ".read": true
      }
    "roomnames: {
      ".read": true
    }
  }
}

With these rules anyone can read the list of room names. But you can only read the messages of a room if you also know the password of the name.

查看更多
登录 后发表回答