【问题标题】:Firebase Security rules for an app with multiple chat rooms具有多个聊天室的应用的 Firebase 安全规则
【发布时间】:2013-08-01 01:51:50
【问题描述】:

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

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

我现在的问题是:

  1. 是否可以配置规则来满足所有这些要求?还是有一些无法满足的要求?

  2. 在通知 Firebase 用户存在时,PHP 服务器必须与 Firebase 通信到什么程度?

【问题讨论】:

    标签: firebase firebase-security


    【解决方案1】:

    首先,check out this gist,这是我前段时间为多个聊天室设计的示例。

    1. 是的。完全有可能。
    2. 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 应用程序进行身份验证。 使用 custom login module 为管理员创建 Firebase 令牌。根据您存储在该令牌中的数据应用安全规则。

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

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

    (或者废弃 PHP 应用程序,直接使用Firebase's baked in authentication!)

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

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

    【讨论】:

    • 这很有帮助!我正在分解您的示例代码,但从概念上讲,我仍在努力连接用户如何使用自定义登录模块进行身份验证,这会转化为授权用户列表中的用户。
    • 从本质上讲,您的安全规则定义了授权用户想要的内容。我使用 /chat/chat_id/users 来存储可以查看聊天的人员列表。您可以轻松地为这些角色(例如版主、用户)添加角色。您创建的身份验证令牌成为auth 对象;如果您使用自定义身份验证,则您决定在其中放入什么,在这种情况下,它将匹配 chat_id/users。
    猜你喜欢
    • 2020-09-10
    • 2017-08-03
    • 2017-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-04
    • 2012-06-25
    • 2016-08-28
    相关资源
    最近更新 更多