允许用户仅访问Firebase数据库中自己的数据?

时间:2017-05-28 18:37:28

标签: firebase firebase-realtime-database hierarchical-data database nosql

我试图拥有这样的数据结构,并确保用户只能提取自己的数据,因为所有处理都是在客户端完成的。

我必须使用哪些数据库安全规则才能使User1可以访问自己的帖子,但无法访问User2的帖子?

(我使用的是Firebase网站)

示例数据库结构:

viewtypes

示例数据库查询:

{
  "posts" : {
    "001" : {
      "text" : "note 1",
      "userID" : "User1"
    },
    "002" : {
      "text" : "note 2",
      "userID" : "User1"
    },
    "003" : {
      "text" : "note 3",
      "userID" : "User2"
    }
  }
}

1 个答案:

答案 0 :(得分:4)

在您当前的结构中,很容易保护每个帖子的创建者的数据访问权限:

{
  "rules": {
    "posts": {
      "$postid": {
        ".read": "data.child('userID').val() === auth.uid"
      }
    }
  }
}

这就是所需要的:现在每个用户只能阅读自己的帖子。

但这种方法存在一个大问题:现在没有人可以从/posts读取,因此没有人可以获得所有帖子的列表。

要授予某人列出帖子的权限,您必须授予他们/posts的读取权限。由于您无法撤销较低级别的权限,这意味着您可以在此时阅读所有帖子,而不仅仅是他们创建的帖子。

这在Firebase中称为rules are not filters:您无法使用规则来过滤数据。我们在Stack Overflow上已经介绍了很多,所以我建议您查看一些other questions on the topic

这个问题有很多解决方案。

二级索引

常见的解决方案是创建每个用户有权访问的帖子ID列表。这通常称为(辅助)索引,并将此附加数据添加到您的模型中:

{
  "userPosts" : {
    "User1": {
      "001" : true,
      "002" : true
    },
    "User2": {
      "003" : true
    }
  }
}

现在您可以像以前一样安全地访问原始帖子,但随后使用以下方法安全访问辅助索引:

{
  "rules": {
    "userPosts": {
      "$userid": {
        ".read": "$userid === auth.uid"
      }
    }
  }
}

因此,每个用户都可以阅读他们有权访问的postID列表,然后可以阅读/posts/postID下的每个帖子。

将每个用户的帖子存储在单独的节点下

在您的情况下,有一个更简单的解决方案。我将这些数据建模为稍微更加层次化,每个用户的帖子都在他们自己的UID下:

{
  "posts" : {
    "User1": {
      "001" : {
        "text" : "note 1",
        "userID" : "User1"
      },
      "002" : {
        "text" : "note 2",
        "userID" : "User1"
      },
    },
    "User2": {
      "003" : {
        "text" : "note 3",
        "userID" : "User2"
      }
    }
  }
}

现在您可以通过以下方式保护访问权限:

{
  "rules": {
    "posts": {
      "$userid": {
        ".read": "$userid === auth.uid"
      }
    }
  }
}

每个用户都可以阅读并列出自己的帖子。但请记住二级索引,因为您迟早可能需要它。