Firestore安全规则中的递归通配符无法按预期工作

时间:2017-11-03 13:23:40

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

我有一个像这样的数据结构(集合文档而不是 JSON 当然你明白了):

{
   users: {
      user1:{
         name: Alice,
         groups: {
            groupA:{subbed:true},
            groupB:{subbed:true}
         }
      },
      user2:{
         name: Bob,
         groups: {
            groupC:{subbed:true},
            groupD:{subbed:true}
         }
      }
   }
}

这基本上是注册用户ID和每个用户订阅的组ID。我想编写一个安全规则,只有当他们是当前的auth用户时才允许访问用户配置文件和子集合,并且根据我对文档的阅读,我认为通配符可以实现这一点......

match /users/{user=**}{
   allow read,write: if user == request.auth.uid;
}

有了这个,我可以正常阅读user文档,但是当我尝试阅读groups子集时,我收到权限错误。我只能通过明确地匹配子集合来使它工作...

match /appUsers/{user}{
   allow read,write: if user == request.auth.uid;

   match /groups/{group}{
      allow read,write: if user == request.auth.uid;
   }
}

...所以我的问题是,两个例子之间的区别是什么以及我对递归通配符的误解是什么?我认为第一个示例的{user=**}部分应该无限制地授予对user文档及其所有子集合,子子集合等的访问权限(对于授权用户)并且应该删除需要专门为存储的数据编写规则,这是我在第二个例子中必须做的。

我只是在短时间内搞乱了Firestore,所以这可能是一个非常愚蠢的问题:)

全部谢谢

3 个答案:

答案 0 :(得分:7)

使用递归时卡时,firebase docs有点令人困惑。我在测试中发现的是,我需要设置两个规则来授予用户写入用户文档和所有子集合(及其子文档)的权限,这是管理用户数据的最合理的设置。

您必须设置两条规则。

  1. 授予用户 / users / {userId} 文档
  2. 的权限
  3. 授予用户对从 / users / {userId} 路径开始的所有子集及其子文档的权限。

    service cloud.firestore { match /databases/{database}/documents { match /users/{userId} { allow read, write: if request.auth.uid == userId; } match /users/{userId}/{document=**} { allow read, write: if request.auth.uid == userId; } } }

  4. Rules

    抱歉包含图片。我无法正确地格式化它们。

答案 1 :(得分:4)

我认为问题在于,当您确实使用子收集通配符=**时,如果user == request.auth.uid,则允许权限,因此这是会发生什么(伪代码):

(访问 users/aHt3vGtyggD5fgGHJ 时)

user = 'aHt3vGtyggD5fgGHJ'
user == request.auth.uid? Yes
allow access

(访问 users/aHt3vGtyggD5fgGHJ/groups/h1s5GDS53 时)

user = 'aHt3vGtyggD5fgGHJ/groups/h1s5GDS53'
user == request.auth.uid? No
deny access

您有两种选择:要么就像您所做的那样并明确匹配子集合,要么使用它:

function checkAuthorization(usr) {
   return usr.split('/')[0] == request.auth.uid;
}
match /users/{user=**}{
   allow read,write: if checkAuthorization(user);
}

(该功能必须在match /databases/{database}/documents内,与您的规则一样)

让我知道这是否有效:)

答案 2 :(得分:0)

安全规则现在具有版本2。

  

... for source in cython_sources: ... options = CompilationOptions(... include_path = includes, # HERE WE GO! ...) result = cython_compile(source, options=options, full_module_name=module_name) 匹配任何文档   子集合以及城市集合中的文档。

     

您必须通过在顶部添加select * from @mytable where [year]+case when len(month) = 1 then '0' + month else month end <= @year+case when len(@month) = 1 then '0' + @month else @month end order by [year]+case when len(month) = 1 then '0' + month else month end desc 选择加入版本2   您的安全规则。

     

here

这对我有用:

match/cities/{city}/{document=**}