我有一个角形网页应用,作为无服务器后端技术的Firebase。目前网络应用程序的目的是让注册用户为提供的产品创建文档。虽然业务用户可以创建无限的产品文档,但是免费用户应该只能创建一个产品文档。
集合:
{id: string, isBusiness: boolean, name: string, email: string, productIds: string[]}
{id: string, title: string, description: string, userId: string}-
每当用户创建新产品-doc时
public createProduct(id: string, product: Product) {
return this.afStore.collection('products').doc(id).set(product, { merge: true });
}我使用触发器onCreate运行一个云函数,将创建的product的id添加到相应用户-doc的productIds字段中。这允许我检查前端if(!user.isBusiness && productIds.length > 1),以限制为免费用户帐户创建多个产品文档。
然而,我最近做了一次笔试,不小心发现,如果您在多个浏览器选项卡上打开网站,同时在每个选项卡上运行createProduct()功能,所有这些选项卡都将执行,允许非业务用户拥有多个产品文档。
有人处理过类似的情况吗?我不知道是否有一种方法可以避免这种情况出现在Firestore安全规则中,或者在活动事务完成之前还有什么需要等待的地方。
发布于 2020-12-16 18:09:08
当前的实现受到了竞争条件的影响:“非业务”用户可能会创建任意数量的产品,直到第一个productId被写入用户文档。
在我看来,解决这一问题最直接的方法是用productId预先填充非商业用户,并限制他们分配新用户的能力。
。
public createProduct(id: string, product: Product, user: User) {
if (user.isBusiness) {
return this.afStore.collection('products').doc(id).set(product, { merge: true });
} else {
return this.afStore.collection('products').doc(user.reservedProductId).set(product, { merge: true });
}
}警告:与任何前端代码一样,这不会阻止恶意参与者按照他们的喜好操作它。如果这种行为是出于安全考虑,则需要限制非业务用户对产品集合的写访问。考虑实现适当的安全规则/云功能。你只能信任后端。
发布于 2020-12-05 15:52:10
在用户中创建一个productCounter节点。然后将您的规则与以下内容合并:
{
"rules": {
"cascade_your_nodes": {
"products": {
"$productId" : {
.".write": "root.child('YOUR_PATHS').child('users').child(auth.uid).child('productCounter').val() < 1 || data.exists() || root.child('YOUR_PATHS').child('users').child(auth.uid).child('isBusiness').val()"
}
}
}
}
}推理:如果不与任何现有规则冲突,则只有在以下情况下才允许写入任何productId:
请求
uid节点的productCounter小于1root.child('YOUR_PATHS').child('users').child(auth.uid).child('productCounter').val() < 1
如果该节点中存在任何数据,则为
data.exists()
如果请求
isBusiness到trueroot.child('YOUR_PATHS').child('users').child(auth.uid).child('isBusiness').val()
https://stackoverflow.com/questions/65158299
复制相似问题