【问题标题】:Understanding Firebase's rules for user-write, global-read了解 Firebase 的用户写入、全局读取规则
【发布时间】:2015-08-31 17:12:31
【问题描述】:

我正在使用 AngularJS 构建一个简单的 Firebase 应用程序。此应用通过 Google 对用户进行身份验证。每个用户都有一个书籍列表。任何人都可以查看书籍,即使它们没有经过身份验证。只有书籍的创建者可以编辑它。但是,个人用户需要能够记录他们已经阅读过一本书,即使是其他人添加的。

我有rules.json 这样的:

{
  "rules": {
    ".read": false,
    ".write": false,
    "book": {
      "$uid": {
        ".write": "auth !== null && auth.uid === $uid",
      }
      ".read": true,
    }
  }
}

我正在尝试简单地写一本书:

$firebaseArray(new Firebase(URL + "/book")).$add({foo: "bar"})

尝试执行此操作时出现“权限被拒绝”错误,尽管我似乎能够read 我在 Forge 中手动创建的书籍。

我还认为存储读者的最佳方式是使其成为图书的属性(一组$uid 供已登录的读者使用)。 ".write" 好像会阻止这个,那我该怎么做呢?

"$uid": {
  ".write": "auth !== null && auth.uid === $uid",
  "readers": {
    ".write": "auth !== null"
  }
},

似乎验证规则在这里也很合适......类似于newData.val() == auth.uid,但我不确定如何验证readers 应该是一个数组(或特别是一组)这些值。

【问题讨论】:

  • 据我所知,您的.read 规则是正确的,因为您的ref 是/book 节点。但我不明白您希望.write 如何发挥作用。注意$add生成一个所谓的push-id,和$uid不一样。看起来您更有可能拥有/book/$bookid 并且在其下,例如creator 具有创建者的uid。然后您可以将book/$bookid/.write 设置为auth != null && (!data.exists() || auth.uid == data.child('creator').val())。
  • @FrankvanPuffelen 是 "$bookid" 与 "$uid" 不同吗?我应该创建一个像"book/$bookid" 这样的规则还是嵌套"book" 和"$bookid"/"$uid" 规则(或者没关系)
  • 任何以$ 开头的都只是一个变量,它可以有任何名称。但$uid 通常用于“user id”节点,因此由auth.uid 标识的节点。由于您是通过 $add 添加图书,因此它们由 push-id 标识。
  • 好问题顺便说一句。很抱歉试图解决在 cmets 中。现在完整答案如下。

标签: firebase angularfire firebase-security firebase-authentication


【解决方案1】:

让我们从一个示例 JSON sn-p 开始:

  "book": {
    "-JRHTHaIs-jNPLXOQivY": { //this is the generated unique id
      "title": "Structuring Data",
      "url": "https://www.firebase.com/docs/web/guide/structuring-data.html",
      "creator": "twiter:4916627"

    },
    "-JRHTHaKuITFIhnj02kE": {
      "title": "Securing Your Data",
      "url": "https://www.firebase.com/docs/security/guide/securing-data.html",
      "creator": "twiter:209103"
    }
  }

所以这是一个包含两个文章链接的列表。每个链接都是由不同的用户添加的,该用户由creator 标识。 creator 的值是 uid,这是 Firebase 身份验证提供的值,可在 auth.uid 下的安全规则中找到。

我将在这里将您的规则分为两部分:

{
  "rules": {
    ".read": false,
    "book": {
      ".read": true,
    }
  }
}

据我所知,您的 .read 规则是正确的,因为您的参考是 /book 节点。

$firebaseArray(new Firebase(URL + "/book"))

请注意,下面的 ref 不起作用,因为您没有顶级节点的读取权限。

$firebaseArray(new Firebase(URL))

现在是.write 规则。首先,您需要在book 级别上授予用户写访问权限。调用$add 意味着您要在该级别下添加一个节点,因此需要写入访问权限。

{
  "rules": {
    "book": {
      ".write": "auth != null"
    }
  }
}

为了清楚起见,我将.read 规则留在这里。

这允许任何经过身份验证的用户写入书节点。这意味着他们可以添加新书(您想要的)和更改现有的书(您不想要的)。

您的最后一个要求是最棘手的。任何用户都可以添加一本书。但是一旦有人添加了一本书,只有那个人可以修改它。在 Firebase 的安全规则中,您可以这样建模:

{
  "rules": {
    "book": {
      ".write": "auth != null",
      "$bookid": {
        ".write": "!data.exists() || auth.uid == data.child('creator').val()"
      }
    }
  }
}

在最后一条规则中,如果或者在这个位置没有当前数据(即它是一本新书)或者如果数据是由当前用户创建的,我们允许编写特定的书。

在上面的例子中,$bookid 只是一个变量名。重要的是,它的规则适用于每一本书。如果需要,我们可以在我们的规则中使用$bookid,它将分别保存-JRHTHaIs-jNPLXOQivY 或-JRHTHaKuITFIhnj02kE。但在这种情况下,不需要这样做。

【讨论】:

  • 我实际上还没有设法测试它,但是在$bookid 下我有readers: {".write": "auth !== null"} - 这应该允许任何用户写入readers 属性,对吗?跨度>
  • 看起来不错,但如果不完全看就很难确定。嵌套具有不同安全约束的数据通常会让人头疼。我会把读者放到一个单独的顶级book_readers 节点中,所以/book_readers/$bookid/$readerid。这样您就可以为读者隔离安全规则。请参阅此处有关“避免嵌套数据”的文档部分:firebase.com/docs/web/guide/…
【解决方案2】:

首先是“权限被拒绝”错误。您收到此错误是因为您尝试直接在“book”节点而不是“book/$uid”中写入。

你现在做什么的例子:

  "book": {
    "-JRHTHaIs-jNPLXOQivY": { //this is the generated unique id
      "foo": "bar"
    },
    "-JRHTHaKuITFIhnj02kE": {
      "foo": "bar"
    }
  }

在您的规则中,您将写入的全局规则设置为 false,因此这将是默认值,并且您为特定节点 book/$uid 制定了规则。因此,当尝试直接在“book”中写入时,它将采用设置为 false 的默认规则。查看 Securing your data 了解有关 firebase 规则的更多信息。

对于您问题的最后一部分,我建议您查看Structuring data,了解有关在 Firebase 中构建数据的最佳方法的更多信息。

因此,请仔细查看您希望在 Firebase 中保存和写入的内容和方式,并确保您的规则具有相应的结构。

【讨论】:

  • 如果我理解正确,.$add 不会直接写入book 节点,而是会写入带有$uid 的子节点。我想我只需要更改写入规则。我认为我建议的结构没有问题,因为它只是记录用户是否读过一本书——我只是想确保所写的是一个有效的、唯一的用户。
  • 发生的事情是 .$add 像使用 push() 函数一样创建了一个唯一的 id。 $uid 是用户 ID。
  • @ExplosionPills 我刚刚在我的答案中添加了一个示例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-10
  • 1970-01-01
  • 2021-06-10
  • 2021-12-11
  • 2016-03-23
  • 1970-01-01
  • 2021-01-21
相关资源
最近更新 更多