Firebase规则仅适用于创建者和管理员用户的对象

时间:2016-12-22 22:32:15

标签: firebase firebase-realtime-database firebase-security mobile-application

我对Firebase规则感到困惑,需要一些帮助。我google了很多,但实际上只是更加困惑,但仍然没有得到它。

假设我有一个像这样的Firebase数据库对象:

root/orders/$id

$id内,我有一个孩子user_id

root/orders/$id/user_id

现在我想要一个只允许用户阅读自己的订单的规则(但不再在现有的一次写入,如何创建新的一次),另外我希望管理员用户读/写全部随时下单。

到目前为止我想出了这个

  "orders": {
    "$id": {
        ".read": "root.child('orders').child($id).child('user_id').val() == auth.uid || root.child('users').child(auth.uid).child('admin').val() == 'user_is_admin'",
        ".write": "root.child('users').child(auth.uid).child('admin').val() == 'user_is_admin'"          
        },
        ".write": "root.child('users').child(auth.uid).child('admin').val() == 'user_is_admin'",
        ".read": "root.child('users').child(auth.uid).child('admin').val() == 'user_is_admin'",                  
        ".indexOn": ["status", "user_id"]
   },

我的管理员在我的用户表中被标记为管理员:

root/users/$id/admin (== user_is_admin)

我的意图是第一部分允许与请求的auth.uid具有相同/orders/$id/user_id的用户阅读他们的订单以及管理员进行读写。管理部分正在运行,但我的用户由于某种原因无权访问。

第二部分是管理员对所有订单的读/写访问权限(没有特定的$id),这也很好,加上普通用户需要写这里创建新订单。

要恢复我的规则的管理部分,但用户部分没有。 1.我的用户无法阅读自己的订单 2.我的用户无法创建新订单

如果有人可以帮助我,我会很高兴。

1 个答案:

答案 0 :(得分:2)

规则:

以下规则应强制执行您在问题中列出的政策:

"orders": {
  "$id": {
    ".read":  "data.child('user_id').val() === auth.uid",
    ".write": "!data.exists() && newData.child('user_id').val() === auth.uid"
  },
  ".write": "root.child('users').child(auth.uid).child('admin').val() === 'user_is_admin'",
  ".read":  "root.child('users').child(auth.uid).child('admin').val() === 'user_is_admin'",
  ".indexOn": ["status", "user_id"]
}

请注意,Firebase安全规则会级联,因此,一旦您为orders的管理员授予了读/写权限,您就不需要重复orders/$id的规则。 (要记住的事情 - 虽然它不是你的规则的问题 - 但是一旦你授予了父母的许可,你就不能在孩子身上撤销它。)

orders/$id/.read规则使用data.child来比较user_idauth.uid。这与您的规则相同,它只是稍微短一点,不包括管理员检查(级联)。

除了检查newData(正在写入的值)是否包含user_id之外,orders/$id/.write规则还会检查data(之前的值)是否存在。这将允许创建,但将拒绝更新和删除。

用户订单:

如您的评论中所述,用户无法查询orders键下的订单列表,因为用户无权阅读其他订单用户(他们需要被过滤掉)。您可以通过按用户存储订单映射来解决问题,如下所示:

"orders": {
    "order_1": {
        "user_id": "user_1",
        ...
    },
    "order_2": {
        "user_id": "user_1",
        ...
    },
    "order_3": {
        "user_id": "user_2",
        ...
    }
},
"ordersByUser": {
    "user_1": {
        "order_1": true,
        "order_2": true
    },
    "user_2": {
        "order_3": true
    }
}

您可以使用Firebase的多地点更新,使维护映射变得不那么繁琐。例如,要为user_1添加其他订单,您可以执行以下操作:

firebase.database().ref().update({
    "orders/order_4": {
        "user_id": "user_1",
        ...
    },
    "ordersByUser/user_1/order_4": true
});

这将允许用户获取订单ID列表(以及订单ID本身),管理员用户仍然可以获得所有订单的列表等。

此外,您应该包含一条规则,以便用户只能在ordersByUser等下阅读自己的订单ID。