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

时间:2015-06-16 03:16:27

标签: firebase angularfire firebase-security firebase-authentication

我正在使用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"})

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

我还认为存储读者的最佳方式是使其成为本书的一个属性(登录读者的一组$uid)。 ".write"似乎会阻止这个,所以我该怎么做?

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

似乎验证规则也适用于newData.val() == auth.uid,但我不确定如何验证readers应该是一个数组(或者具体来说)一组这些价值观。

2 个答案:

答案 0 :(得分:7)

让我们从一个示例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"))

请注意,下面的参考号不起作用,因为您没有对顶级节点的读访问权。

$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。但在这种情况下,不需要这样做。

答案 1 :(得分:2)

首先关闭"许可被拒绝"错误。您收到此错误是因为您正试图直接在" book"节点而不是" book / $ uid"。

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

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

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

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

所以taka要仔细研究你想要保存和写入firebase的内容和方式,并确保你的规则是相应的结构。