具有多个聊天室的应用程序的Firebase安全规则

具有多个聊天室的应用程序的Firebase安全规则,firebase,firebase-security,Firebase,Firebase Security,我很难想象这样的应用程序的安全规则会是什么样子: 一个带多个聊天室的firebase 版主通过单独的PHP应用程序进行身份验证 版主只有修改自己聊天室的权限,他们可以阅读、写入、更新和删除聊天室中的任何内容 来宾通过单独的PHP应用程序到达并进行身份验证 来宾具有读写权限,但不能删除任何内容 我现在的问题是: 是否可以配置规则以满足所有这些要求?还是有一些不可能满足的要求 在通知Firebase存在用户时,PHP服务器必须在多大程度上与Firebase通信 首先,这是我不久前为多个聊天室设计

我很难想象这样的应用程序的安全规则会是什么样子:

  • 一个带多个聊天室的firebase
  • 版主通过单独的PHP应用程序进行身份验证
  • 版主只有修改自己聊天室的权限,他们可以阅读、写入、更新和删除聊天室中的任何内容
  • 来宾通过单独的PHP应用程序到达并进行身份验证
  • 来宾具有读写权限,但不能删除任何内容
我现在的问题是:

  • 是否可以配置规则以满足所有这些要求?还是有一些不可能满足的要求

  • 在通知Firebase存在用户时,PHP服务器必须在多大程度上与Firebase通信

  • 首先,这是我不久前为多个聊天室设计的一个示例

  • 对。这是完全可能的
  • PHP服务器?您不需要任何服务器!:) 数据结构基本如下:

    # 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/...
    
    安全规则是自我记录的。这是一个本地副本,用于引用完整性

    {
      "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()"
                  }
               }
            }
         }
      }
    
    }
    
    版主通过单独的PHP应用程序进行身份验证。 使用为管理员创建Firebase令牌。根据存储在该令牌中的数据应用安全规则

    版主只有修改自己聊天室的权限… 通过简单地扩展上面的用户权限,这应该是不言自明的

    来宾通过单独的PHP应用程序到达并进行身份验证。 使用为管理员创建Firebase令牌。根据存储在该令牌中的数据应用安全规则

    (或者放弃PHP应用程序,直接使用!)

    来宾具有读写权限,但不能删除任何内容。 在“.write”规则中使用newData.exists()或newData.hasChildren(…)以防止删除

    客人不能欺骗其他客人。
    身份验证令牌将防止这种情况

    这非常有用!我正在分解您的示例代码,但从概念上讲,我仍在努力连接用户如何通过自定义登录模块进行身份验证,这将转换为授权用户列表中的用户。本质上,您的安全规则定义了授权用户想要什么。我使用/chat/chat\u id/users来存储可以查看聊天的人的列表。您也可以轻松地为这些角色添加角色(例如主持人、用户)。您创建的身份验证令牌成为
    auth
    对象;如果您使用custom auth,那么您可以决定将什么放入其中,在本例中,它将匹配聊天室id/用户。