Node.js用户数据更新异常:仅测试账户可更新数据的问题排查
问题描述
用多个账户测试Node.js应用时,明明登录的是其他用户,更新操作却只会修改测试账户的description字段。重写代码后问题依旧,怀疑是user-controller.js和user-service.js的数据传递出了问题。
相关代码如下:
router.js
router.put('/updateUser/:id', userController.update);
controller.js
class UserController { async updateUser(req, res, next) { try { const userUpdate = await userService.update(req); return res.json(userUpdate); } catch (e) { next(e); } } }
service.js
class UserService { async updateUser(req) { const userUpdate = await UserModel.findOneAndUpdate( req.params.id, req.body.user, { new: true } ); const userDto = new UserDto(userUpdate); return { user: userDto }; } }
user-dto.js
module.exports = class UserDto { email; id; description; constructor(model) { this.email = model.email; this.id = model._id; this.description = model.description } }
user-model.js
const UserSchema = new Schema({ email: { type: String, unique: true, required: true }, password: { type: String, required: true }, description: { city: { type: String }, brand: { type: String }, }, });
问题分析与修复方案
1. 路由与控制器方法不匹配
router里配置的是调用userController.update,但控制器里的方法名是updateUser,这会导致请求无法触发正确的处理逻辑,可能走错误分支或直接报错。
修复:
修改router.js中的方法映射:
router.put('/updateUser/:id', userController.updateUser);
2. Mongoose更新语法错误
findOneAndUpdate的第一个参数需要是查询条件对象,直接传req.params.id的话,Mongoose会把它当成{ 'req.params.id': undefined }处理,根本定位不到正确用户,甚至可能错误匹配到测试账户。
修复:
在service.js中修正查询条件:
async updateUser(req) { const userUpdate = await UserModel.findOneAndUpdate( { _id: req.params.id }, // 改为按_id查询的对象 req.body.user, { new: true, runValidators: true // 可选:开启更新时的Schema校验,避免非法数据 } ); // 增加错误处理,避免更新不存在的用户 if (!userUpdate) { throw new Error('目标用户不存在'); } const userDto = new UserDto(userUpdate); return { user: userDto }; }
3. 缺失登录用户身份校验(核心问题)
当前代码完全依赖URL参数里的id决定更新哪个用户,没有校验当前登录用户ID和目标ID是否一致。也就是说,只要请求里传测试账户的ID,不管登录的是谁,都会更新测试账户的数据——这就是问题的根本原因。
修复:
第一步:确保路由经过登录校验
假设你有登录认证中间件(比如JWT校验、Passport),先把路由保护起来:
// router.js // authMiddleware是你的登录校验中间件,执行后req.user会包含当前登录用户的信息 router.put('/updateUser/:id', authMiddleware, userController.updateUser);
第二步:在控制器中校验身份一致性
// controller.js async updateUser(req, res, next) { try { // 检查当前登录用户ID和要更新的用户ID是否一致 if (req.user.id !== req.params.id) { return res.status(403).json({ message: '无权修改该用户的数据' }); } const userUpdate = await userService.update(req); return res.json(userUpdate); } catch (e) { next(e); } }
4. 验证前端请求数据格式
确认前端发送的请求体结构和Schema匹配,比如更新description时,请求体应该是:
{ "user": { "description": { "city": "上海", "brand": "新品牌" } } }
内容的提问来源于stack exchange,提问作者wannnwdooo
相关产品推荐
相关产品推荐

