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

Exp*_*lls 3 firebase firebase-security angularfire firebase-authentication

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

rules.json喜欢这样:

{
  "rules": {
    ".read": false,
    ".write": false,
    "book": {
      "$uid": {
        ".write": "auth !== null && auth.uid === $uid",
      }
      ".read": true,
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

而我正试着写一本书,只需:

$firebaseArray(new Firebase(URL + "/book")).$add({foo: "bar"})
Run Code Online (Sandbox Code Playgroud)

尝试这样做时,我收到"许可被拒绝"错误,虽然我似乎能够read在Forge中手动创建书籍.

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

"$uid": {
  ".write": "auth !== null && auth.uid === $uid",
  "readers": {
    ".write": "auth !== null"
  }
},
Run Code Online (Sandbox Code Playgroud)

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

Fra*_*len 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"
    }
  }
Run Code Online (Sandbox Code Playgroud)

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

我将你的规则分为两部分:

{
  "rules": {
    ".read": false,
    "book": {
      ".read": true,
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

据我所知,你的.read规则是正确的,因为你的ref是/ book节点.

$firebaseArray(new Firebase(URL + "/book"))
Run Code Online (Sandbox Code Playgroud)

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

$firebaseArray(new Firebase(URL))
Run Code Online (Sandbox Code Playgroud)

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

{
  "rules": {
    "book": {
      ".write": "auth != null"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

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

  • 它看起来还不错,但如果不完全看清楚就很难确定.嵌套具有不同安全约束的数据通常会导致令人头疼的问题.我将读者放入一个单独的顶级`book_readers`节点,所以`/ book_readers/$ bookid/$ readerid`.这样您就可以为读者隔离安全规则.请参阅文档部分"避免嵌套数据":https://www.firebase.com/docs/web/guide/structuring-data.html#section-denormalizing-data (2认同)