Firebase 实时数据库安全规则允许更新但未设置

Posted

技术标签:

【中文标题】Firebase 实时数据库安全规则允许更新但未设置【英文标题】:Firebase Realtime Database Security Rules allow update but not set 【发布时间】:2021-02-20 05:18:16 【问题描述】:

这些是我关于数据库中用户节点的安全规则。

    "users": 
      "$uid": 
        ".read": "auth != null && $uid === auth.uid",
        "$user_nodes": 
          ".write": "(auth != null && $uid === auth.uid) || (auth == null && $user_nodes.contains('connection'))"
        
      
    

当我通过身份验证并尝试阅读我的 auth.uid 下的全部信息时,使用这些规则一切正常。出于某种原因,虽然整个节点不允许 set 操作,但 update 操作是允许的。有人可以向我解释为什么会这样吗?

编辑:所以在代码中读取操作看起来像这样:

userRef.child(auth.getCurrentUser().getUid()).addListenerForSingleValueEvent(new ValueEventListener() ...);

集合操作看起来像这样:

userRef.child(auth.getCurrentUser().getUid()).setValue(...);

我无法向您显示确切的代码,因为我在 rules playground 中测试规则时实际遇到了我上面解释的行为。

【问题讨论】:

请编辑问题以显示在这些规则下无法按您预期的方式运行的应用代码示例。我们应该能够复制您显示的内容并自己运行以观察相同的行为。 @DougStevenson 我刚刚编辑了这个问题。但正如我所说的那样,我无法真正显示确切的代码,因为这种行为是在规则操场上经历过的。这对我的应用程序来说并不是什么大问题,但我只是想知道为什么在规则操场中,允许对整个节点 $uid 进行更新操作,但设置操作不符合这些确切的规则。 【参考方案1】:

这是你的代码:

userRef.child(auth.getCurrentUser().getUid()).setValue(...);

此代码尝试对/users/$uid 进行设置,根据您的安全规则,这是不允许的。因此,如果写入被拒绝,那将按预期工作。

根据您的规则,客户端可以写入或删除任何子节点,但不能写入或删除/users/$uid 本身。这也是update 语句起作用的原因:它有效地对update 调用中存在的每个属性执行set() 操作,根据规则允许的。

考虑删除操作可能最容易看出这里的区别:您的规则允许用户删除/users/$uid 的任何子节点,但他们不能一次性删除/users/$uid

【讨论】:

哦,我想我现在明白了。所以基本上update 语句为/users/$uid 下的每个子节点执行set 操作,这就是规则游乐场允许它的原因?

以上是关于Firebase 实时数据库安全规则允许更新但未设置的主要内容,如果未能解决你的问题,请参考以下文章

Firebase 安全规则:只允许更新一个字段

如何为实时数据库设置安全规则,但允许注册新用户并创建哈希图?

如何在firebase实时数据库中编写规则?

Firebase 电子邮件说我的实时数据库有不安全的规则

Firebase 实时数据库,安全规则 - 检查其他节点

Firebase 实时电话数据库安全规则