Node.js Bcryptjs:如何实现用户更新时密码非必填?
解决用户更新接口密码非必填的bcrypt哈希报错问题
问题分析
当前用户更新接口要求必须传入密码,否则bcrypt.hashSync会因接收undefined作为第一个参数抛出以下错误:
Error: Illegal arguments: undefined, string at Object.bcrypt.hashSync (/home/pc/api_foodelivery/node_modules/bcryptjs/dist/bcrypt.js:189:19) at exports.update (/home/pc/api_foodelivery/src/controllers/UserController/UpdateUser.js:16:37) at processTicksAndRejections (node:internal/process/task_queues:96:5)
原因是代码中强制对password进行哈希,未处理密码未传入的场景,导致更新接口无法仅修改非密码字段。
解决方案
通过动态构建更新数据对象,仅在密码存在时执行哈希操作,实现密码非必填的更新逻辑:
const db = require('../../models/index'); const bcrypt = require('bcryptjs'); exports.update = async (req, res) => { const { id } = req.params; const { firstName, lastName, email, password, phoneNumber } = req.body; try { const user = await db.User.findOne({ where: { id } }); if (!user) { return res.status(401).json('User does not exist'); } // 动态构建需要更新的字段集合 const updateData = {}; if (firstName) updateData.firstName = firstName; if (lastName) updateData.lastName = lastName; if (email) updateData.email = email; if (phoneNumber) updateData.phoneNumber = phoneNumber; // 仅当请求体中包含有效密码时,才哈希并更新密码 if (password) { updateData.password = bcrypt.hashSync(password, 8); } await user.update(updateData); return res.status(200).json('User updated!'); } catch (err) { console.log(err); return res.status(500).json('Server error'); } }
关键优化点
- 动态更新字段:避免强制覆盖所有字段,仅更新请求体中传入的有效字段,保留用户原有未修改的数据
- 密码条件哈希:仅当
password存在且不为空时,才执行哈希操作并加入更新对象,避免undefined参数报错 - 错误处理优化:在捕获异常时返回500状态码给前端,而非仅打印日志,保证接口的响应完整性
补充说明
如果需要支持传入空字符串清空密码(不推荐此操作),可将密码判断条件改为if (password !== undefined),但通常建议仅在密码有实际修改值时才处理哈希逻辑。
内容的提问来源于stack exchange,提问作者Routfin
相关产品推荐
相关产品推荐

