Node.js如何实现仅停车场数据原发布商户拥有编辑权限
实现方案
首先明确前置要求:你的Parking集合Schema必须新增/已有存储发布者ID的字段,比如命名为merchantId,字段值对应该停车场发布商户在Auth表中的_id,发布停车场的接口里要同步把当前登录商户的ID写入这个字段,否则无法做归属校验。
现有代码存在4个核心问题:
- 没有校验当前登录用户的角色,普通用户、provider角色只要拿到有效token就能调用接口
- 更新停车场时没有校验数据归属,任意登录用户只要知道parkingId就能修改任意停车场数据
- 路由定义了路径参数
:id,但代码却从req.body取parkingId,参数逻辑不一致 - 异常捕获没有返回正确的HTTP状态码,直接返回错误字符串不符合接口规范
具体修改逻辑
- 优先从路径参数
req.params.id获取要操作的停车场ID,避免body传参被篡改 - 校验当前登录用户角色,非merchant(角色值≠2)直接返回403无权限
- 执行更新时,把当前登录用户ID作为查询条件的一部分,匹配
_id = 停车场ID 且 merchantId = 当前用户ID,从数据库层面拦截越权操作 - 根据update操作返回的匹配条数判断操作结果:匹配条数为0说明要么停车场不存在,要么当前用户不是该停车场的发布者,可根据业务需求返回403/404
- 修复异常捕获的返回逻辑,返回正确的状态码和错误信息
修改后完整代码
exports.updateParking = async (req, res) => { try { // 从路径参数取停车场ID,和路由定义的:id对应 const parkingId = req.params.id; const { parkingName, price, address, name, phoneNumber, about } = req.body; // 校验用户存在且角色是merchant(角色值2) const currentUser = await Auth.findById(req.data.id); if (!currentUser) return res.status(404).json({ error: "用户不存在" }); if (currentUser.role !== 2) { return res.status(403).json({ error: "仅商户角色有权限操作停车场数据" }); } // 更新时同时匹配停车场ID和所属商户ID,从查询层避免越权 const updateResult = await Parking.updateOne( { _id: parkingId, merchantId: req.data.id // 核心校验:仅匹配当前用户自己发布的停车场 }, { $set: { parkingName, price, address, name, phoneNumber, about // 其他待更新字段 }, } ); // 没有匹配到对应记录:要么停车场不存在,要么不是当前用户所有 if (updateResult.matchedCount === 0) { return res.status(403).json({ error: "你无权修改该停车场信息,或停车场不存在" }); } return res.status(200).json({ success: true, msg: "停车场信息更新成功", }); } catch (error) { // 修复原代码异常无状态码的问题 return res.status(500).json({ error: error.message }); } };
可选优化
如果业务上需要明确区分「停车场不存在」和「无权限修改」两种错误提示,可以在执行update前先查询一次停车场记录做判断:
const parking = await Parking.findById(parkingId); if (!parking) return res.status(404).json({ error: "停车场不存在" }); // 注意ID要转成字符串对比,MongoDB默认返回的_id是ObjectId类型,直接和字符串ID对比会不相等 if (parking.merchantId.toString() !== req.data.id.toString()) { return res.status(403).json({ error: "你无权修改该停车场信息" }); } // 两层校验都通过后再执行更新操作
内容的提问来源于stack exchange,提问作者user19038939
相关产品推荐
相关产品推荐

