了解 Firebase 的用户写入、全局读取规则



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

我有这样的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应该是这些值的数组(或特别是一组)。

让我们从一个示例 JSON 代码段开始:

  "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规则。

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

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

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

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

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

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

您现在要做的事情的示例:

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

在您的规则中,您将一个全局写入规则设置为 false,因此这将是默认值,然后您为特定节点 book/$uid 制定了规则。因此,当尝试直接在"book"中写入时,它将采用设置为 false 的默认规则。请参阅保护您的数据,详细了解 Firebase 规则。

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

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

最新更新