I am having trouble imagining what the security rules would look like for an application that looks like this:
My questions right now are these:
Is it possible to configure the rules to meet all these requirements? Or are there some requirements that cannot possibly be met?
To what extent does the PHP Server have to communicate with Firebase, in notifying Firebase of the existence of users?
First of all, check out this gist, which is an example I worked up some time ago for multiple chat rooms.
The data structure is basically as follows:
# chats roughly equal "rooms"
/chats/chat_id/users/...
# a timestamp of when each participant last viewed the room
/chats/chat_id/last/...
# the messages sent
/chats/chat_id/messages/...
The security rules are self documenting. Here's a local copy for referential integrity.
{
"chat": {
// the list of chats may not be listed (no .read permissions here)
// a chat conversation
"$key": {
// if the chat hasn't been created yet, we allow read so there is a way
// to check this and create it; if it already exists, then authenticated
// user (specified by auth.account) must be in $key/users
".read": "auth != null && (!data.exists() || data.child('users').hasChild(auth.account))",
// list of users authorized to participate in chat
"users": {
// if the list doesn't exist, anybody can create it
// if it already exists, only users already in the list may modify it
".write": "!data.exists() || data.hasChild(auth.account)",
"$acc": {
// for now the value is just a 1, later it could be a read/write/super privilege
".validate": "newData.isNumber()"
}
},
// timestamps recording last time each user has read this chat
"last": {
"$acc": {
// may only written by the authenticated user and if user is in $key/users
".write": "$acc === auth.account && root.child('chat/'+$key+'/users').hasChild($acc)",
".validate": "newData.isNumber()"
}
},
"messages": {
"$msg": {
// to write a message, it must have all three fields (usr, ts, and msg)
// and the person writing must be in $key/users
".write": "root.child('chat/'+$key+'/users').hasChild(auth.account)",
".validate":"newData.hasChildren(['ts', 'usr', 'msg'])",
"usr": {
// may only create messages from myself
".validate": "newData.val() === auth.account"
},
"msg": {
".validate": "newData.isString()"
},
"ts": {
".validate": "newData.isNumber()"
}
}
}
}
}
}
A moderator authenticates via a separate PHP application. Use the custom login module to create a Firebase token for admins. Apply the security rules according to the data you store in that token.
Moderators only have permission to modify their own chat room... This should be pretty self explanatory by simply extending the user permissions above.
Guests arrive and authenticate via the separate PHP application. Use the custom login module to create a Firebase token for admins. Apply the security rules according to the data you store in that token.
(Or scrap the PHP app and just use Firebase's baked in authentication!)
Guests have read and write access, but may not delete anything. Use newData.exists() or newData.hasChildren(...) inside the ".write" rule to prevent deletion.
Guests cannot spoof other guests. Authentication tokens will prevent this
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With