如何通过Firestore安全规则基于资源路径锁定Firestore集合组查询

时间:2019-09-23 17:47:43

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

我正在应用中实现Firestore集合组查询,并且我想制定一个安全规则,以锁定对拥有尝试查询资源的用户的访问权限

Firestore中的数据的结构类似于users/1234/.../posts/5678。我想提取通过收集组查询的资源的路径,然后将提取的userId(在这种情况下为1234)传递到我的signedIn()方法中,该方法仅针对自定义令牌。我知道此signedIn()方法可以正常工作,因为我有其他依赖该方法的规则也可以正常工作。

我在firestore.rules文件中尝试了以下操作:

// collection groups
match /{path=**}/posts/{post} {
  allow read: if resource['__name__'][0] == "users" && signedIn(resource['__name__'][1])
}

AND

// collection groups
match /{path=**}/posts/{post} {
  allow read: if path[0] == "users" && signedIn(path[1])
}

不幸的是,使用这两种方法中的任何一种,当我尝试查询posts集合组时,仍然会出现权限被拒绝的错误。我什至找不到任何好的方法来调试它,因为仪表板中的Simulator对于集合组查询似乎并不是很有用。

P.S。我知道我可以将userId字段添加到post文档中,然后编写如下规则:

// collection groups
match /{path=**}/posts/{post} {
  allow read: if signedIn(resource.data.userId)
}

实际上,我已经尝试过并使其起作用。但是出于商业原因,我宁愿尽可能不要这样做。

1 个答案:

答案 0 :(得分:0)

您是否要限制用户进行数据库调用,以仅允许他们查看属于该用户的帖子?

这是Firestore规则中的signedIn方法的外观:

function signedIn() {
  return request.auth.uid != null;
}

以及一种将用户限制为仅在与他们的uid相同的路径内进行粗操作的方法

match /users/{userId}/posts/{postsId} {
  allow create, read, update: if request.auth.uid == userId && signedIn();
}