Правила безопасности Firebase: ограничивайте запись только этим uid, за исключением нескольких полей
В Firebase у меня есть users
"node" , который выглядит так:
users: {
someUid: {
username: 'someUsername'
activeConversations: {},
profile_picture: ''
... lots of other children
},
...
},
anotherNode: {
},
... hundreds of other nodes
Мои правила прямо сейчас:
{
"rules": {
".read": true,
".write": true,
"users": {
".indexOn": [
"username"
]
},
"friendRequests": {
".indexOn": [
"timeSent"
]
}
}
}
Что я хочу сделать, это ограничить доступ к дочерним элементам в users
"node" только клиенту, которому принадлежит ребенок. Так, например, дочерний someUid
должен записываться только клиентом с помощью uid someUid
. Другой "node" как anotherNode
может быть доступен для записи/чтения любым зарегистрированным клиентом.
Кроме того, любой зарегистрированный клиент должен иметь возможность писать на profile_picture
и activeConversations
в документе users
.
Как я могу достичь этого без необходимости устанавливать правило чтения/записи для каждого node?
Спасибо
Ответы
Ответ 1
Наличие ".read": true, ".write": true
в корне вашей базы данных - это идея очень плохой. Буквально каждый мог просто стереть всю вашу базу данных или вставить любые данные в любое время. Это связано с тем, что .read
и .write
управляют каскадом, поэтому, если вы оцениваете значение true
на некотором node, у человека есть разрешение для всех дочерних элементов этого node.
К счастью, более безопасные правила, такие как правила, которые вы предлагаете, просты в реализации. Я предполагаю, что someUid
равен пользователям auth.uid
, которые вы можете сделать:
{
"rules": {
"users": {
".indexOn": ["username"],
// wildcard, matches any node under 'users'
"$someUid": {
".read": "auth != null",
".write":"auth != null",
"$other" : {
".validate": "($other == 'profile_picture' || $other == 'activeConversations') || auth.uid == $someUid" // only that own user can change their username
}
}
}
}
}
Я пропустил ваш friendRequests
node, потому что я не уверен, какие правила безопасности вы хотите для этого, но я надеюсь, что этого достаточно, чтобы вы начали.
Firebase docs очень хорошо описывают этот материал.
Ответ 2
Я думаю, что @Bradley Mackey был почти там, но просто нуждался в небольшой настройке.
{
"rules": {
"users": {
".indexOn": ["username"],
// wildcard, matches any node under 'users'
"$someUid": {
"$other" : {
".read": "($other == 'profile_picture' || $other == 'activeConversations') || auth.uid == $someUid",
".write": "($other == 'profile_picture' || $other == 'activeConversations') || auth.uid == $someUid",
}
}
},
"$anythingelse": {
".read": "auth != null",
".write": "auth != null",
}
}
}
Поле ".validate":
гарантирует, что поле соответствует определенному формату. Чтение и запись здесь должны дать каждому доступ к чтению и записи, если поле является профилем profile_picture или activeConversations, и предоставить пользователю доступ ко всему остальному.
EDIT:
Я добавил в другое правило, которое позволит доступ на чтение и запись любому подписанному пользователю к любому из узлов, не являющихся пользователями.
Ответ 3
В соответствии с документацией firebase вы можете ограничить права доступа на уровне пользователя и уровне данных
Например,
// These rules grant access to a node matching the authenticated
// user ID from the Firebase auth token
{
"rules": {
"users": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
Кроме того, вы можете ограничить разрешение записи на чтение на уровне данных,
{
"rules": {
"messages": {
"$message": {
// only messages from the last ten minutes can be read
".read": "data.child('timestamp').val() > (now - 600000)",
// new messages must have a string content and a number timestamp
".validate": "newData.hasChildren(['content', 'timestamp']) && newData.child('content').isString() && newData.child('timestamp').isNumber()"
}
}
}
}
Пройдите через официальную документацию по firebase,
https://firebase.google.com/docs/database/security/quickstart
https://firebase.google.com/docs/database/security/user-security
https://firebase.google.com/docs/database/security/securing-data