【问题标题】:firebase security rules all auth users can add a new post and only user who created his post can edit itfirebase 安全规则所有身份验证用户都可以添加新帖子,只有创建帖子的用户才能编辑它
【发布时间】:2020-10-18 23:12:15
【问题描述】:

我目前正在开发一个所有身份验证用户都可以创建帖子的页面。帖子也应该是可编辑的,但只能由创建者编辑。此外,具有特定电子邮件地址的管理员应该能够编辑帖子。

这是我的安全角色:

{
  "rules": {
    "shoes" : {
      ".read": true,
        "$shoeID" : {
          ".write" : "root.child('shoes').child($shoeID).child('postowner').val() === auth.uid && auth != null && root.child('users').child(auth.uid).child('uid').val() === auth.uid || auth.token.email === 'admin@admin.com'"
        }
    },
    "websites" : {
      ".read": true,
        "$shoeID" : {
          "$storeID" : {
             ".write" : "root.child('websites').child($shoeID).child($storeID).child('postowner').val() === auth.uid && auth != null && root.child('users').child(auth.uid).child('uid').val() === auth.uid || auth.token.email === 'admin@admin.com'" 
          }
        }
    },
    "users" : {
      "$uid" : {
        ".read" : "auth != null && root.child('users').child($uid).child('uid').val() === auth.uid"
      }
    } 
  }
}

这是我的数据库结构:

我认为我做错了什么,因为按照我当前的规则,任何用户都可以更改数据。

【问题讨论】:

  • 不太可能是问题的原因,但节目的写入规则中的root.child('users').child(auth.uid).child('uid').val() === auth.uid 对我来说似乎是个问题。如果您想强制执行该完整性,您只需要在对/users/$uid 的写入操作中执行此操作,而不是在每个单独的鞋子写入中。

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


【解决方案1】:

我不确定问题出在哪里,但这条规则对我来说似乎过于复杂:

".write" : "
  root.child('shoes').child($shoeID).child('postowner').val() === auth.uid 
  && auth != null 
  && root.child('users').child(auth.uid).child('uid').val() === auth.uid 
  || auth.token.email === 'admin@admin.com'
"

可以改进的地方:

  • 您已经使用了auth.uid之后无需检查auth != null。要么先移动空检查,要么完全跳过它。
  • 无需通过$shoeID 查找鞋子,因为它已经在data 中。所以你的root.child('shoes').child($shoeID) 等同于(更短更惯用的)data
  • root.child('users').child(auth.uid).child('uid').val() === auth.uid 子句在鞋子的写操作中似乎没有意义。该子句只能在/users/$user的写操作中强制执行。

通过这些更改,您的规则变为:

".write" : "
  data.child('postowner').val() === auth.uid 
  || auth.token.email === 'admin@admin.com'
"

如前所述:我看不出写入操作中出了什么问题,但希望您使用更简单的规则可以更轻松地解决该问题。我建议从规则游乐场开始,并使用它来重播您的代码所做的事情。

【讨论】:

  • 我已经按照你的描述缩短了我的规则。但是,如果我仅将此规则用作测试目的: data.child('postowner').val() === auth.uid 我无法使用任何用户写入数据库。
  • 没有人可以使用这些规则创建新的鞋节点,但同样适用于您问题中的规则。这样做的原因是您需要检查newData 而不是data,因为您关心写操作之后 之后的数据(如果允许的话),而data(和root 在您的原始代码中)是 写入操作之前的数据。
  • 我已经设法用这个做到了:"$shoeID" : { ".write" : "data.exists() && data.child('postowner').val() === auth.uid || !data.exists() || !newData.exists()" } 。谢谢你的帮助!!!
猜你喜欢
  • 1970-01-01
  • 2019-08-08
  • 2021-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-02
相关资源
最近更新 更多