允许用户只访问他们自己在 Firebase 数据库中的数据?
Allow users access only to their own data in Firebase database?
我正在尝试拥有这样的数据结构,并确保用户只能提取他们自己的数据,因为所有处理都是在客户端完成的。
我必须使用什么数据库安全规则才能让 User1 可以访问他们自己的帖子,但不能访问 User2 的帖子?
(我正在使用 Firebase 网络)
示例数据库结构:
{
"posts" : {
"001" : {
"text" : "note 1",
"userID" : "User1"
},
"002" : {
"text" : "note 2",
"userID" : "User1"
},
"003" : {
"text" : "note 3",
"userID" : "User2"
}
}
}
示例数据库查询:
firebase.database().ref('/posts/').once('value').then(function(snapshot) {
console.log(snapshot.val()); // Returns all 3 posts
});
在您当前的结构中,很容易保护每个 post 的创建者的数据访问:
{
"rules": {
"posts": {
"$postid": {
".read": "data.child('userID').val() === auth.uid"
}
}
}
}
这就是所需要的:现在每个用户只能阅读他们自己的 posts。
但是这种方法有一个大问题:现在没有人可以从 /posts
读取,所以没有人可以得到所有 post 的列表。
要授予某人列出 post 的能力,您必须授予他们对 /posts
的读取权限。由于您无法撤销较低级别的权限,这意味着您此时他们可以阅读 所有 posts,而不仅仅是他们创建的那些。
这在 Firebase 中称为 rules are not filters: you cannot use rules to filter data. We've covered it quite a bit here on Stack Overflow, so I recommend you also check out some other questions on the topic。
这个问题有很多解决办法。
二级索引
一个常见的解决方案是创建每个用户都可以访问的 post ID 的列表。这通常称为(二级)索引并将此附加数据添加到您的模型中:
{
"userPosts" : {
"User1": {
"001" : true,
"002" : true
},
"User2": {
"003" : true
}
}
}
现在您可以像以前一样保护对原始 post 的访问,但随后可以使用以下方法保护对二级索引的访问:
{
"rules": {
"userPosts": {
"$userid": {
".read": "$userid === auth.uid"
}
}
}
}
因此每个用户都可以读取他们有权访问的 postID 列表,然后可以读取 /posts/postID
下的每个 post。
将每个用户的 post 存储在单独的节点下
对于您的情况,有一个更简单的解决方案。我会将该数据建模得稍微分层一些,每个用户的 posts 在他们自己的 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"
}
}
}
}
每个用户都可以阅读和列出他们自己的 post。但是请牢记二级索引,因为您迟早可能需要它。
我正在尝试拥有这样的数据结构,并确保用户只能提取他们自己的数据,因为所有处理都是在客户端完成的。
我必须使用什么数据库安全规则才能让 User1 可以访问他们自己的帖子,但不能访问 User2 的帖子?
(我正在使用 Firebase 网络)
示例数据库结构:
{
"posts" : {
"001" : {
"text" : "note 1",
"userID" : "User1"
},
"002" : {
"text" : "note 2",
"userID" : "User1"
},
"003" : {
"text" : "note 3",
"userID" : "User2"
}
}
}
示例数据库查询:
firebase.database().ref('/posts/').once('value').then(function(snapshot) {
console.log(snapshot.val()); // Returns all 3 posts
});
在您当前的结构中,很容易保护每个 post 的创建者的数据访问:
{
"rules": {
"posts": {
"$postid": {
".read": "data.child('userID').val() === auth.uid"
}
}
}
}
这就是所需要的:现在每个用户只能阅读他们自己的 posts。
但是这种方法有一个大问题:现在没有人可以从 /posts
读取,所以没有人可以得到所有 post 的列表。
要授予某人列出 post 的能力,您必须授予他们对 /posts
的读取权限。由于您无法撤销较低级别的权限,这意味着您此时他们可以阅读 所有 posts,而不仅仅是他们创建的那些。
这在 Firebase 中称为 rules are not filters: you cannot use rules to filter data. We've covered it quite a bit here on Stack Overflow, so I recommend you also check out some other questions on the topic。
这个问题有很多解决办法。
二级索引
一个常见的解决方案是创建每个用户都可以访问的 post ID 的列表。这通常称为(二级)索引并将此附加数据添加到您的模型中:
{
"userPosts" : {
"User1": {
"001" : true,
"002" : true
},
"User2": {
"003" : true
}
}
}
现在您可以像以前一样保护对原始 post 的访问,但随后可以使用以下方法保护对二级索引的访问:
{
"rules": {
"userPosts": {
"$userid": {
".read": "$userid === auth.uid"
}
}
}
}
因此每个用户都可以读取他们有权访问的 postID 列表,然后可以读取 /posts/postID
下的每个 post。
将每个用户的 post 存储在单独的节点下
对于您的情况,有一个更简单的解决方案。我会将该数据建模得稍微分层一些,每个用户的 posts 在他们自己的 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"
}
}
}
}
每个用户都可以阅读和列出他们自己的 post。但是请牢记二级索引,因为您迟早可能需要它。