sin*_*enm 10 rules admin firebase access google-cloud-firestore
在火力地堡公司的FireStore,我想只允许(自定义设定),管理员写/更新/删除资源,为此,我已经得到了这些安全规则:
service cloud.firestore {
match /databases/{database}/documents {
match /resources {
allow read;
allow write, update, delete: if get(/users/$(request.auth.uid).isAdmin);
}
match /resources/{resource} {
allow read;
allow write, update, delete: if get(/users/$(request.auth.uid).isAdmin);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我正在使用在users集合中标记为admin的用户登录:

NfwIQAjfNdS85yDvd5yPVDyMTUj2是从身份验证窗格获取的UID:

但是,出于某种原因(更新:确定原因;请参阅答案),在确定我已经使用admin用户登录后,在写入资源集合时,我收到了PERMISSION_DENIED错误.
也许可以从Firestore查看请求日志?然后,我可以看看request.auth.uid与我的收藏和规则相匹配的内容.
sin*_*enm 13
在写我的问题时,我让它成功了!我犯了两个错误,如果我正确阅读文档,这两个错误都可以避免.
首先,对服务定义函数的 所有调用都get需要在路径前加上/ databases/$(database)/ documents /.所以这个规则:
allow write: if get(/users/$(request.auth.uid)).isAdmin;
Run Code Online (Sandbox Code Playgroud)
成为这个:
allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).isAdmin;
Run Code Online (Sandbox Code Playgroud)
我知道,这很长,但事实就是如此.我不确定为什么Firestore本身无法做到这一点,因为看到相同的路径前缀在所有调用中保持不变get,但也许这是为了未来尚未准备好的某些功能,例如跨数据库查询或其他什么.
其次,该get函数将返回一个资源,而您又需要调用.data它来获取它包含的实际数据.因此,而不是这样做:
get(/path/to/user/).isAdmin
Run Code Online (Sandbox Code Playgroud)
你需要这样做:
get(/path/to/user/).data.isAdmin
Run Code Online (Sandbox Code Playgroud)
现在我只希望我能够将该逻辑提取到用户定义的函数中:
function isAdmin() {
return get(/databases/$(database)/documents/users/$(request.auth.uid)).data.isAdmin;
}
Run Code Online (Sandbox Code Playgroud)
但这样做会再次导致PERMISSION_DENIED,并且在不知道函数中实际发生了什么的情况下,我不确定我是否会花更多的时间来尝试解决这个问题.
更新: @Hareesh 指出函数必须在匹配器的范围内定义,因此可以将函数放在默认的顶级匹配器中,如下所示:
service cloud.firestore {
match /databases/{database}/documents {
function isAdmin() {
return get(/databases/$(database)/documents/users/$(request.auth.uid)).data.isAdmin == true;
}
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3725 次 |
| 最近记录: |