根据docs函数无法创建变量,但是我需要检查两个字段以获取对companies
集合的写权限。我将user
上的documentId存储为company_slug
所以match /companies/{company} { allow write: ... }
的规则#1是
get(/databases/$(database)/documents/users/$(request.auth.uid)).data.company_slug == company
这对读取访问权限很好,但是我需要检查user.level
(对于管理员来说是1,对于其他级别是2-n)是否可以写。
因此规则2将是
get(/databases/$(database)/documents/users/$(request.auth.uid)).data.level == 1
因此完整的规则是:
match /companies/{company} {
allow read: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.company_slug == company;
allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.company_slug == company && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.level == 1;
}
哪个看上去很笨拙,而且我发送的每个写入请求也会“花费”我2次读取和1次写入,不是吗?
有什么方法可以对此进行优化,因为随着应用程序的增长,这似乎很难维护。
答案 0 :(得分:2)
您可以使用Custom Claims来满足您的安全需求。
您将为每个用户分配两个不同的声明:
companyId
和
userLevel
(1、2、3等)
您的规则如下:
service cloud.firestore {
match /databases/{database}/documents {
function userIsLevel1() {
return (request.auth.uid != null) && (request.auth.token.userLevel == 1);
}
function isCorrectCompany(company) {
return request.auth.token.companyId == company;
}
match /companies/{company} {
allow read: if isCorrectCompany(company);
allow write: if isCorrectCompany(company) && userIsLevel1();
}
}
使用“自定义声明”的一个主要优点是,您无需为每次安全规则验证都阅读一个或多个Firestore文档。
您可以观看17:49开始的Firebase官方视频:https://www.youtube.com/watch?v=eW5MdE3ZcAw