Pee*_*Jee 3 firebase firebase-security google-cloud-firestore
我目前正在使用 Firestore 数据库为我的应用编写一些规则。目前每个人都可以读取数据,经过身份验证的用户可以写入。
match /quizzes/{quizId} {
allow read;
allow write: if request.auth != null;
}
Run Code Online (Sandbox Code Playgroud)
这工作正常,但我也希望未经身份验证的用户只写入文档中的特定键。
文档内容示例:
{
title: 'title',
plays: 12,
playedBy: [//Filled with user id's],
...
}
Run Code Online (Sandbox Code Playgroud)
有什么方法可以限制未经身份验证的用户只能对playedBy 数组进行写访问,而不能对该文档的其他键进行写访问?
在之前的回答之后(我相信是 2019 年末),Firebase 引入了Map.diff。
就像是:
match /quizzes/{quizId} {
allow read;
allow write: if request.auth != null ||
request.resource.data.diff(resource.data).affectedKeys() == ["playedBy"].toSet()
}
Run Code Online (Sandbox Code Playgroud)
肯定的事。但是如果你有很多领域,它可能会变得有点复杂。
让我们从最简单的例子开始。像这样的东西允许未经身份验证的用户编写playedBy只要这是文档中唯一的字段:
if request.auth != null || request.resource.data.keys().hasOnly(['playedBy'])
Run Code Online (Sandbox Code Playgroud)
如果未经身份验证的用户正在创建新文档或更新现有文档,则此方法有效。但是一旦文档包含更多字段,它就会停止,因为request.resource.data包含了写入成功后文档将具有的所有字段。
因此,更好的替代方法是检查仅playedBy修改了 ,并且所有其他字段都具有与以前相同的值。棘手的一点是处理不存在的字段,我通常使用一些辅助函数来处理:
function isUnmodified(key) {
return request.resource.data[key] == resource.data[key]
}
function isNotExisting(key) {
return !(key in request.resource.data) && (!exists(resource) || !(key in resource.data));
}
Run Code Online (Sandbox Code Playgroud)
进而:
if request.auth != null &&
request.resource.data.keys().hasOnly(['title', 'plays', 'playedBy']) &&
isUnmodified('title') &&
isUnmodified('plays')
Run Code Online (Sandbox Code Playgroud)
确切的规则可能有点偏离,但我希望这足以让您自己完成。
| 归档时间: |
|
| 查看次数: |
872 次 |
| 最近记录: |