Firestore的集合组权限

时间:2019-05-26 12:21:00

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

我有以下规则:

match /suuntoAppAccessTokens/{userName} {
      allow create: if request.auth.uid != null && request.auth.token.firebase.sign_in_provider != 'anonymous';
      match /tokens/{userID} {
        allow read, write, create, update, delete: if request.auth.uid == userID && request.auth.token.firebase.sign_in_provider != 'anonymous';
      }
    }

match /{path=**}/tokens/{userID} {
            allow read, write, create, update, delete: if request.auth.uid == userID;
    }

这意味着当前用户应该有权访问路径/suuntoAppAccessTokens/dimitrioskanellopoulos/tokens/{userID}

但是,当我这样查询集合组时:

return this.afs.collectionGroup('tokens').snapshotChanges();

我收到一个权限错误。

直接在tokes / {userID}下获取文档可以正常工作。

我该怎么做,以便当前用户可以运行collectionGroup查询并根据我的规则获取允许其获取的项目?

1 个答案:

答案 0 :(得分:2)

您的规则期望安全规则将过滤所有tokens集合中的所有文档,以便仅读取当前用户的文档。使用安全规则是不可能的。 安全规则不是过滤器。来自documentation

  

在编写查询以检索文档时,请记住安全性   规则不是过滤器-查询全部或全部。为了节省您的时间,   资源,Cloud Firestore根据潜在查询评估查询   结果集,而不是所有您的实际字段值   文件。如果查询可能返回文档,   客户端没有读取权限,整个请求失败。

您需要将查询更改为客户端仅请求完全希望当前用户可读的文档。不幸的是,我无法确定您当前的模式是否可行。文档{userId}的ID不能在集合组查询中用于过滤文档。因此,您都必须确保满足以下两个条件:

  • 您将需要在文档中过滤一些字段以完成此工作。
  • 您将需要调整您的安全规则以完全匹配客户端的要求。

我建议使用令牌将用户的uid存储在文档中,该令牌与规则中的{userId}相同。您可以像这样查询它:

collectionGroup('tokens').where("uid", "==", uid)

确保客户端正确传入uid

此外,您还需要确保规则按照完全相同的条件授予访问权限:

match /{path=**}/tokens/{userID} {
  allow read, write, create, update, delete:
    if request.auth.uid == resource.data.uid;
}

仅当文档的uid字段与身份验证uid相同时才允许访问该文档,而这正是客户端所要求的。