Firestore安全规则基于请求查询值

时间:2018-02-24 10:02:48

标签: firebase google-cloud-firestore firebase-security

我正在尝试保护对集合的请求以允许任何单个get,但只有在匹配特定密钥时才允许list

数据库结构如下:

projects
  project1
    name: "Project 1 name"
    board_id: "board1"
  project2
    name: "Project 2 name"
    board_id: "board2"

boards
  board1
  board2

我从Vue发出的Firestore查询:

// Only return projects matching the requested board_id

db
  .collection("projects")
  .where("board_id", "==", this.board_id)

我想要的安全规则是这样的:

match /projects/{project} {
  allow get: if true // this works
  allow list: if resource.data.board_id == [** the board_id in the query **]

  // OR

  allow list: if [** the board_id in the query **] != null

我想这样做,这样你就可以列出特定主板上的项目,但不能只列出所有内容。

有没有办法在安全规则中访问请求的.where(),还是我需要将projects集合嵌套到我的boards集合中并以此方式保护它?

1 个答案:

答案 0 :(得分:1)

这实际上取决于您将来如何查询数据。如果您没有要求列出所有项目(无论董事会如何),那么您当前的数据模型会更好,并且可以通过将允许的板添加为映射{board_id: true}或(理想情况下)子集来保证/ users文档。

当前数据模型

数据库

/projects/{project_id}
/boards/{board_id}
/users/{uid}/boardPermissions/{board_id}

安全规则

match /projects/{project} {
  allow list: if exists(/databases/$(database)/documents/users/$(request.auth.uid)/boardPermissions/${resource.data.board_id})

替代数据模型

如果你想完全分区你的数据(我倾向于为我的许多项目做的事情),那么创建以下模型

数据库

/boards/{board_id}/projects/{project_id}
/users/{uid}/boardPermissions/{board_id}

安全规则

match /boards/{board_id}/projects/{project_id} {
  allow list: if exists(/databases/$(database)/documents/users/$(request.auth.uid)/boardPermissions/${board_id})