根据docs函数不能创建变量,但我需要在companies
集合上检查两个字段的写权限。我将documentId存储在我的user
文档中,作为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次写入,不是吗?
有没有办法优化它,因为随着应用程序的增长,这似乎很难维护。
您可以使用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文档。
你可以观看这个官方的Firebase视频,从17:49开始:https://www.youtube.com/watch?v=eW5MdE3ZcAw