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

Slb*_*box 4 database hierarchical-data nosql firebase firebase-realtime-database

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

我必须使用什么数据库安全规则,以便User1可以访问自己的帖子,但不能访问User2的帖子?

(我正在使用Firebase网站)

示例数据库结构:

{
  "posts" : {
    "001" : {
      "text" : "note 1",
      "userID" : "User1"
    },
    "002" : {
      "text" : "note 2",
      "userID" : "User1"
    },
    "003" : {
      "text" : "note 3",
      "userID" : "User2"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

示例数据库查询:

firebase.database().ref('/posts/').once('value').then(function(snapshot) {
  console.log(snapshot.val()); // Returns all 3 posts
});
Run Code Online (Sandbox Code Playgroud)

Fra*_*len 6

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

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

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

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

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

在Firebase中这是众所周知的,因为规则不是过滤器:您不能使用规则来过滤数据。我们已经在Stack Overflow上对此进行了相当多的介绍,因此我建议您也查看有关此主题的其他问题

有很多解决方案。

次要指标

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

{
  "userPosts" : {
    "User1": {
      "001" : true,
      "002" : true
    },
    "User2": {
      "003" : true
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以像以前一样保护对原始帖子的访问,但是可以使用以下方法保护对二级索引的访问:

{
  "rules": {
    "userPosts": {
      "$userid": {
        ".read": "$userid === auth.uid"
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

因此,每个用户都可以阅读他们有权访问的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"
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以使用以下方法保护访问权限:

{
  "rules": {
    "posts": {
      "$userid": {
        ".read": "$userid === auth.uid"
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

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