使用数组元素的Firebase身份验证规则

时间:2020-09-08 17:14:25

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

我将Firebase与本机一起使用。在我的应用程序中,我允许用户与以下用户共享内容:与特定用户或全部共享读取,复制或修改权限。 由于Firebase不提供查询的OR功能,因此我使用数组来存储user:permission组合,以便可以使用array-contains-any的任何功能来进行查询

.where("access", "array-contains-any", [user_id, `${user_id}:R`, `${user_id}:C`, `${user_id}:M`, "All_R", "All_C", "All_M"])

这使我可以查询user_id所拥有的所有内容,或者可以与user_id共享,或者具有R,C或M权限也可以与“ All”共享。

现在,我想对身份验证规则进行类似的操作(这样,只有具有“ M”权限的用户才能进行修改等),方法是将经过身份验证的用户ID与数组中的用户ID进行比较。为此,它将需要类似于“ array-contains-any”的功能以及用于身份验证规则的字符串连接。

有可能还是我需要做些不同的事情?

1 个答案:

答案 0 :(得分:3)

我进行了一些测试,并认为我得到了您正在使用的类型的子集。我将逐步执行以下步骤,以便您可以从最后开始进行构建。


第一步是使此查询生效:

ref.where("access", "array-contains", user_id)

这很容易通过以下方式保护:

allow list: if request.auth != null && request.auth.uid in resource.data.access;

如果access数组中提到了他们的UID,则任何人都可以阅读文档。


下一步是允许该查询:

ref.where("access", "array-contains-any", [user_id, user_id+":R"]);

当我们按照之前的规则运行此命令时,则不允许这样做。那是因为我们要求的是规则不知道的值。

要使其正常运行,请将规则更改为:

allow list: if request.auth != null && (
  request.auth.uid in resource.data.access || 
  request.auth.uid+":R" in resource.data.access
);

所以现在代码和规则中的条件再次匹配,并且允许读取。


如果我们为所有访问规则添加另一个条件:

ref.where("access", "array-contains-any", [user_id, user_id+":R", "All_R"]);

然后再次使用上述规则,我们的权限将被拒绝,因为我们在查询中有一个规则不知道的值。

要解决此问题,我们也在规则中检查该值:

allow list: if request.auth != null && (
  request.auth.uid in resource.data.access || 
  request.auth.uid+":R" in resource.data.access ||
  "All:R" in resource.data.access
);

使用这些规则,查询将再次成功。


此时,您可以在此处添加其他条件,它应该可以工作。