设置
我在 Firebase Firestore 中有一个集合,其中包含以下字段:
(["active" , "created" , "description" , "displayName" , "expires" , "image" , "type" , "uid" , "userName"])
where "expires"
是可选的。
写入规则确保每个对象都遵循该形式并成功测试。
问题
当尝试从集合中读取时,我有一条规则,规定如下:
let seeUnexpired = !("expires" in resource.data.keys()) ||
resource.data.expires > request.time ||
request.auth.uid == resource.data.uid;
这禁止除作者之外的用户阅读过期的条目。然而,这条规则并不禁止读取。我正在使用带有精心策划的数据的本地模拟器进行测试,并且确信过期字段存在并且对于此测试来说已经过时。
Details
在尝试调试时,我发现导致规则失败的条件是!("expires" in resource.data.keys())
.
运行测试debug(resource.data.keys())
打印出这个对象到firestore-debug.log
:
list_value {
values {
string_value: "active"
}
}
where "active"
仅在请求中使用此查询条件时显示:...collection('collection_name').where('active', '==', true).get()
.
这向我表明resource.data.keys()
仅包含资源中引用的字段where
关于读取请求的条款。这意味着请求可以通过简单地不在查询中包含“字段不得存在”规则来规避该规则。
Debug:
Mar 31, 2021 12:34:48 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFO: Detected non-HTTP/2 connection.
list_value {
values {
string_value: "active"
}
}
Tests
Test:
await firestoreAdmin.collection(COLLECTIONS.items).doc(mockItem.id).update({active: true, expires: new Date('01 Jan 2000 00:00:00 GMT')});
const query = firestore.collection(COLLECTIONS.items).where('active', '==', true); //unAuthed firestore instance
await assertFails(query.get());
Rule:
function readItemRules() {
let seeActive = resource.data.active == true || request.auth.uid == resource.data.uid;
let seeUnexpired = !("expires" in resource.data.keys()) ||
resource.data.expires > request.time ||
request.auth.uid == resource.data.uid; TODO figure out expiration rules
return seeActive && seeUnexpired;
}
Data:
问题
我对这个问题的理解是否准确,或者我是否遗漏了细节或语法怪癖?这种行为是故意的吗?如果是的话,我应该如何修改我的规则/数据以强制执行这种安全性?