Javascript 为什么我的Firebase Firestore安全规则允许对现有文档执行.set()操作,但.set()缺少字段
这是我在stackoverflow上提出的第一个问题,所以如果我遗漏了问题的某些方面,请告诉我 我的目标是理解为什么当创建的文档缺少下面列出的firestore规则所需的字段时,下面显示的mocha测试会通过 摩卡测试代码(请注意,项目ID已检查并正常工作,但此处省略) 消防队规则Javascript 为什么我的Firebase Firestore安全规则允许对现有文档执行.set()操作,但.set()缺少字段,javascript,firebase,google-cloud-firestore,mocha.js,firebase-security,Javascript,Firebase,Google Cloud Firestore,Mocha.js,Firebase Security,这是我在stackoverflow上提出的第一个问题,所以如果我遗漏了问题的某些方面,请告诉我 我的目标是理解为什么当创建的文档缺少下面列出的firestore规则所需的字段时,下面显示的mocha测试会通过 摩卡测试代码(请注意,项目ID已检查并正常工作,但此处省略) 消防队规则 rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { function docum
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
function documentFieldsCheckOut(requiredFields, allowedFields){
let requiredAndAllowed = requiredFields.concat(allowedFields);
return request.resource.data.keys().hasAll(requiredFields) &&
request.resource.data.keys().hasOnly(requiredAndAllowed);
}
function updateHasOnlyAllowedFields(allowedFields){
return debug(request.resource.data.keys()).hasOnly(allowedFields);
}
match /{document=**} {
allow read, write: if false;
}
match /posts/{postID} {
allow update: if ((resource.data.authorID == request.auth.uid) || userIsModerator())
&& updateHasOnlyAllowedFields(["visibility", "content"]);
allow create: if (request.resource.data.authorID == request.auth.uid) &&
documentFieldsCheckOut(["authorID", "content", "visibility", "headline"],
["photo", "location", "tags"]);
}
}
}
注意:注释掉wait admin.doc(postPath).set({authord:myID,content:“content”,visibility:“private”,headline:“headline”})代码>导致测试按预期失败。
此外,将中的.set更改为.update将等待firebase.assertsuccessed(docRef.set({}))代码>还会导致测试按预期失败。如果我理解正确,您会问为什么此调用成功:
const admin = getAdminFirestore();
admin.doc(postPath).set({authorID:myID, content:"content",
visibility:"private",
headline:"headline"});
使用管理权限的调用绕过数据库的安全规则。因此,无论您的安全规则如何,此调用都不会被它们拒绝
第二次写入操作不同:
const db = getFirestore(myAuth);
const docRef = db.doc(postPath);
docRef.set({})
这一次,据我所知,您将通过一个非管理员参考,这意味着写入必须遵守安全规则才能被接受。非常感谢您的快速回复!问题是为什么写操作docRef.set({})
成功,而下面的安全规则应该拒绝写操作允许创建:如果documentFieldsCheckOut([“作者”、“内容”、“可见性”、“标题”]、“照片”、“位置”、“标记”]);`执行相同的.docRef.set({})操作而不首先创建具有管理权限的文档失败。换句话说,规则似乎允许使用绕过创建规则的.set()来“覆盖”现有数据,但我敢打赌我遗漏了什么!你可能想澄清你的问题,因为我仍然很难理解为什么你认为在这种情况下应该拒绝第二封信。谢谢你让我回顾我的问题!在进一步减少代码并运行更多测试之后,我发现我错误地认为.set()方法总是算作Firestore规则中的create。但是,当文档位于.set()之前时,它似乎被算作“更新”方法。由于我在规则中授予了允许不包含必填字段的更新的权限,用户可能会将其文档“更新”为空白文档:D请让我知道这是否是错误的结论,并再次感谢您的帮助!!!
const db = getFirestore(myAuth);
const docRef = db.doc(postPath);
docRef.set({})