首页 > 解决方案 > Firebase 实时规则:允许多个用户访问数据

问题描述

所以我的数据库结构是这样的,所有者在创建组时设置,所有者应该有权添加其他用户,以便他们也可以访问和编辑数据。

-Groups
   |-Groupname
      |- Owner: string
      |- Allowed: List<string>
      |- Data: all the data

所以我的尝试是这些规则,但是当我使用游乐场功能时,它们在所有者下保存的 uid 或允许时不起作用:

"Groups" : {
      "$group": {
        ".read": "auth != null && (data.child('Owner').val() === auth.uid || data.child('Allowed').val() === auth.uid)",
        ".write": "auth != null && (data.child('Owner').val() === auth.uid || data.child('Allowed').val() === auth.uid)"
                }
           }

当这些规则有效时,用户是否仍然能够创建新组?数据库和错误的图片:1 2 3

标签: firebase-realtime-databasefirebase-security

解决方案


首先,在实时数据库中,避免使用数组,而是使用映射。

改变这个:

"Allowed": {
  "0": "8ZiQGBPFkiZOLgLJBgDeLw9ie9D3",
  "1": "KEuhrxnAWXS0dnotjhjFAYUOcm42",
  "2": "48yULftKSxgyS84ZJC4hs4ug4Ei2"
}

对此:

"Allowed": {
  "8ZiQGBPFkiZOLgLJBgDeLw9ie9D3": true,
  "KEuhrxnAWXS0dnotjhjFAYUOcm42": true,
  "48yULftKSxgyS84ZJC4hs4ug4Ei2": true
}

阅读链接的博客文章以获取更多信息,但简而言之,它使添加/删除用户变得非常简单:

const groupRef = firebase.database.ref(`Groups/${groupId}`);

// add a user
groupRef.child("E04HLbIjGDRUQxsRReHSKifaXIr2").set(true);

// remove a user
groupRef.child("KEuhrxnAWXS0dnotjhjFAYUOcm42").remove();

您也可以更改true为您想要的任何内容。这里有些例子:

  • false= 参与者,true= 主持人
  • false= 只读,true= 可以编辑
  • 角色名称:"member", "admin","moderator"
  • 权限级别:(0成员)、500(版主)、1000(所有者)等(确保将它们分开,您不想在和之间添加一个级别01并且必须编辑整个数据库)。

但最重要的一点是,实时数据库安全规则不了解数组。data.val()不会返回一个数组,它只会返回一个标记值,上面写着“非空对象在这里!”。这意味着安全规则需要映射。

本参考文档涵盖了您可以在实时数据库安全规则中使用的结构和变量。

使用您提出的规则,您尝试允许组中的任何用户能够写入组的数据 - 但您无法管理他们可以写入和不能写入的内容。组的任何恶意成员都可以添加/删除其他任何人,使自己成为所有者,甚至完全删除组。

{
  "rules": {
    "Groups" : {
      "$group": {
        // If this group doesn't exist, allow the read.
        // If the group does exist, only the owner & it's members
        // can read this group's entire data tree.
        ".read": "!data.exists() || (auth != null && (data.child('Owner').val() === auth.uid || data.child('Allowed').child(auth.uid).val() === true))",

        "Owner": {
          // Only the current owner can write data to this key if it exists.
          // If the owner is not yet set, they can only claim it for themselves.
          ".write": "auth != null && (data.val() === auth.uid || (!data.exists() && newData.val() === auth.uid))",

          // Force this value to be a string
          ".validate": "newData.isString()"
        },

        "Allowed": {
          // Only the owner can edit the entire member list
          // For a new group, the owner is also granted write access
          // for it's creation
          ".write": "auth != null && (data.parent().child('Owner').val() === auth.uid || (!data.exists() && newData.parent().child('Owner').val() === auth.uid))",

          "$member": {
            // Allows the user to remove themselves from the group
            ".write": "auth != null && auth.uid === $member && !newData.exists()",

            // Force this value to be a boolean
            ".validate": "newData.isBoolean()"
          }
        },

        "Data": {
          // The owner and members can edit anything under "Data"
          // Currently this includes deleting everything under it!
          // For a new group, the owner is also granted write access
          // for it's creation
          // TODO: tighten structure of "Data" like above
          ".write": "auth != null && (data.parent().child('Owner').val() === auth.uid || data.parent().child('Allowed').child(auth.uid).val() === true || (!data.exists() && newData.parent().child('Owner').val() === auth.uid))"
        }
      }
    }
  }
}

推荐阅读