You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Cloud Firestore安全规则中仅允许负值更新?

问题:Cloud Firestore安全规则限制积分仅可扣除

我使用React、RTK Query和Cloud Firestore开发客户端应用,用户可积累积分用于购买商品,但订单环节的积分扣除存在安全漏洞——当前的Firestore安全规则允许用户修改自己的积分,但无法阻止用户给自己增加积分。

当前安全规则代码:

function isOwner(userId){
    return request.auth.uid == userId;
  }
function isSignedIn() {
    return request.auth != null;
  }

match /users/{userId} {
  allow update: 
    if request.resource.data.diff(resource.data).changedKeys().hasOnly(["points"])
       && isSignedIn() && isOwner(userId);
}

对应的RTK Query mutation代码:

userPayment: builder.mutation({
  async queryFn(data) {
    try {
      const docRef = doc(db, "users", data.userId);
      await updateDoc(docRef, {
        points: increment(-data.totalPrice)
      })
      return {data: "payment successful"}
    } catch (err) {
      return {error: err}
    }
  },
  invalidatesTags: ["UserData"]
}),

解决方案

修改安全规则,仅允许积分减少

你可以通过对比更新前后的积分值,在安全规则中限制只能扣除积分(即新积分≤旧积分)。修改后的规则如下:

function isOwner(userId){
    return request.auth.uid == userId;
  }
function isSignedIn() {
    return request.auth != null;
  }

match /users/{userId} {
  allow update: 
    if request.resource.data.diff(resource.data).changedKeys().hasOnly(["points"])
       && isSignedIn() && isOwner(userId)
       // 限制更新后的积分不大于原有积分,仅允许扣除或保持不变
       && request.resource.data.points <= resource.data.points;
}

可选优化:防止积分变为负数

如果需要避免用户积分被扣至负数,可以额外添加一个条件:

&& request.resource.data.points >= 0

这样修改后,即便客户端被篡改发送增加积分的请求,Firestore安全规则也会直接拒绝操作,从根源上保证积分扣除的安全性——仅依赖前端RTK Query的逻辑确实不够,必须通过后端安全规则加固。

内容的提问来源于stack exchange,提问作者Navih

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 09:05:16