【问题标题】:Firebase data structure and security rulesFirebase 数据结构和安全规则
【发布时间】:2016-03-12 05:11:22
【问题描述】:

我在使用 firebase 的安全规则时遇到了问题,而且我不是 100% 会出错。我在想也许我的数据结构有误:

{
"users": {
    "uid": {
        "displayName": "Name";
    }

},
"modules": {
    "id": {
        "title": "buttons",
        "uid": "(user id string)"
    },
    "id": {
        "title": "navbars",
        "uid": "(user id string)"
    }
},
"snippets": {
    "id = moduleID": {
        "id (of snippet)": "(id string)" {
            "uid (user ID)": "(string)",
            "body": {
                "css": "(some code)",
                "html": "(Some code)",
                "name": "(string)",
                "description": "(string)"
            }
        }
    }
}

应用程序中的一切工作正常,但是当我开始添加安全规则时,我收到了拒绝访问错误。我只是想知道我的数据结构一开始是正确的还是安全规则完全错误?

安全规则:

{
"rules": {
    "users": {
        "$uid": {
            // grants write and read access to the owner of this user account whose uid must exactly match the key ($uid)
            ".write": "auth != null && auth.uid == $uid",
            ".read": "auth != null && auth.uid == $uid"

        }
    },
    "snippets": {
        "$uid": {
            // grants write and read access to the owner of this user account whose uid must exactly match the key ($uid)
            ".write": "auth != null && auth.uid == $uid",
            ".read": "auth != null && auth.uid == $uid"
        }
    },
    "modules": {
        "$uid": {
            // grants write and read access to the owner of this user account whose uid must exactly match the key ($uid)
            ".write": "auth != null && auth.uid == $uid",
            ".read": "auth != null && auth.uid == $uid"
        }
    }
}

任何建议将不胜感激。

【问题讨论】:

  • 您在哪里看到拒绝访问错误?你能发布一个拒绝读/写的代码的sn-p吗?
  • 该应用程序使用正常的基本规则,但当使用新规则更新时,它会完全中断。控制台给出此错误错误:permission_denied:客户端没有访问所需数据的权限。在错误(本机)
  • 尝试应用仪表板中的模拟器选项卡;这使您可以分析规则如何应用于任何读/写操作,而无需进行身份验证。
  • auth != null && 很有价值,但在这里技术上是多余的。 auth.uid === $uid 检查将短路并且仍然评估为假。在这种情况下,这只是一个细微差别,但却是一个需要理解的重要概念,因为当您尝试在具有 || 的复杂规则中使用 auth.uid 时,它可能会咬到您,它可能会短路并避免评估 ||标准。
  • @kato 感谢您的意见,我会注意的。我完全迷失了这一点,刚刚开始再次阅读文档并阅读 NoSql。我认为我需要更好地理解这些概念,而不是试图强迫它发挥作用。干杯:)

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


【解决方案1】:

根据数据结构,规则似乎格式不正确。

规则在每个节点中都有 $uid,但您的数据不匹配。用户有 uid,但模块有 id,sn-ps 有 id = moduleID。

$uid 是一个保存节点名称的变量,因此它可以在 {} 中引用,因此您应该(为了便于阅读)将其他两个节点中的变量重命名为在每个 {} 中更有意义的名称。就像在模块中一样,拥有它 $module_id。

但是。我认为这个笑话是你想限制阅读 sn-ps 和模块给经过身份验证的用户。为此,您可以引用用户节点。

.read 规则是这样的

"modules": {
    "$module_id": {
        ".read": "auth != null && root.child('users/' + auth.id).exists()
    }

因此,经过身份验证的用户可以读取您的模块节点,并且他们的 uid 也出现在用户/节点中

【讨论】:

  • 感谢您的意见,我已经注意到这一点,这是有道理的,但仍然有错误。我想要发生的是让用户只看到他们的数据,而不是其他用户数据。仍然试图弄清楚这里的一般规则到底发生了什么,所以要做更多的研究,我很难理解它。
  • 是的...为每种情况制定正确的规则确实具有挑战性。我们有一个类似的设置,其中一个用户(在我们的例子中是一组用户)应该只能从该组用户读取数据。无论如何,我都不是专家,但是在敲打了我的头(和桌子)几个星期之后,我们终于找到了它,所以不要放弃。
【解决方案2】:

您是否使用 Firebase Bolt 编译器生成规则?我不得不编写一些复杂的规则,并且手工编写很快就会变得混乱。

下面是它的样子。非常容易进行更改、编译和试用。

//current logged in user
isUser(uid) = auth != null && auth.uid == uid;
//does this module id exist
hasValidModule(module_id) = root['modules'][module_id] != null;

//dont let anyone read or write to top node
path / {
    read() = false;
    write() = false;
}
path /users/$user_id 
{   
    write() = isUser($user_id);
    read() = isUser($user_id);
}
path /snippets/$module_id/$snipit_id/$user_id 
{   
    write() = isUser($user_id) && hasValidModule($module_id);
    read() = isUser($user_id);
}
path /modules/$user_id 
{   
    write() = isUser($user_id);
    read() = isUser($user_id);
}

这是它吐出的 json:

{
  "rules": {
    "users": {
      "$user_id": {
        ".read": "auth != null && auth.uid == $user_id",
        ".write": "auth != null && auth.uid == $user_id"
      }
    },
    "snippets": {
      "$module_id": {
        "$snipit_id": {
          "$user_id": {
            ".read": "auth != null && auth.uid == $user_id",
            ".write": "auth != null && auth.uid == $user_id && newData.parent().parent().parent().parent().child('modules').child($module_id).val() != null"
          }
        }
      }
    },
    "modules": {
      "$user_id": {
        ".read": "auth != null && auth.uid == $user_id",
        ".write": "auth != null && auth.uid == $user_id"
      }
    }
  }
}

Firebase 博客上有一些信息,但真正帮助我的文档是这个

https://github.com/firebase/bolt/blob/master/docs/language.md

【讨论】:

  • 感谢您的意见,看起来很棒。但我想在使用任何工具之前先尝试了解这些规则以及它们是如何工作的。它给出的规则也不起作用。我意识到我需要重新构建我的数据和 Angular 代码以获得我正在寻找的结果。我试图将规则用作过滤器,但我现在意识到这不是它的本意。当我弄清楚时,我会更新这篇文章。再次感谢。
猜你喜欢
  • 2016-09-16
  • 2016-07-16
  • 2015-07-12
  • 2014-11-10
  • 2018-09-03
  • 2018-09-21
  • 2021-04-09
  • 1970-01-01
  • 2016-06-27
相关资源
最近更新 更多