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

CRUD删除权限异常:创建者删除自身支出时提示未授权

问题分析与修复方案

核心问题:类型不匹配导致授权校验失败

普通用户删除自己创建的支出记录时触发403未授权错误,根源是**req.userId与expense.userID的类型不匹配**:

  • req.userId来自JWT payload,是字符串格式的用户ID
  • expense.userID是MongoDB存储的ObjectId对象
    直接用!==比较时,字符串和ObjectId对象永远不相等,导致权限校验逻辑误判。

修复步骤

1. 修正权限校验逻辑

删除冗余的requestingUser查询(JWT中间件已将role挂载到req对象上),并将expense.userID转为字符串后再做比较:

export const deleteExpense = async (req, res, next) => {
  try {
    const expense = await Expense.findById(req.params.id);
    if (!expense) return error404(req, res, next);

    // 修正权限判断:统一转为字符串比较,直接使用req.role
    if (req.userId !== expense.userID.toString() && req.role !== "manager") {
      return error403(req, res, next);
    }

    const deletedExpense = await Expense.findByIdAndDelete(req.params.id);
    if (!deletedExpense) return res.status(404).send("Expense not found"); // 修正错误提示文本
    res.status(200).json({ message: "deleted" });
  } catch (error) {
    errorServer(error, req, res, next);
  }
};

2. 确认JWT签发逻辑(可选)

确保签发JWT时,payload中的id是字符串格式的用户ID,示例签发逻辑:

const token = jwt.sign(
  { id: user._id.toString(), role: user.role },
  process.env.JWT_KEY,
  { expiresIn: "1d" }
);

额外优化点

  • 移除不必要的User.findById(req.userId)查询,减少数据库请求开销
  • 修正删除失败时的错误提示(原代码中"House not found"属于笔误)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 08:52:48