Node.js中使用bcrypt.compare触发Illegal arguments错误如何修复
问题修复方案
你遇到的Error: Illegal arguments: string, undefined报错是因为bcrypt.compare方法调用参数缺失导致的,该方法要求传入两个必填参数:
- 第一个参数:用户输入的明文密码
- 第二个参数:数据库中存储的已加密的哈希密码
你当前代码只传入了明文密码一个参数,第二个参数为undefined,所以触发参数类型非法报错。同时登录验证的逻辑也存在问题:应该先根据用户名查询对应用户,拿到用户存储的哈希密码后,再调用bcrypt对比明文密码和哈希密码是否匹配,而不是先对比再查询,更不能把密码对比结果作为查询条件传入User.findOne。
修复后代码
router.post('/loguser', async (req, res) => { // 先做参数合法性校验,避免空值报错 if (!req.body.username || !req.body.password) { return res.status(400).send('用户名和密码不能为空') } try { // 第一步:先根据用户名查询用户 const user = await User.findOne({ username: req.body.username }) if (!user) { console.log('用户不存在') return res.status(401).send('用户名或密码错误') } // 第二步:将用户输入的明文密码和数据库存储的哈希密码对比 const isPasswordValid = await bcrypt.compare(req.body.password, user.password) if (isPasswordValid) { console.log('用户验证通过') // 可在此处添加登录态生成逻辑,比如生成token返回 return res.send('登录成功') } else { console.log('密码错误') return res.status(401).send('用户名或密码错误') } } catch (err) { console.error('登录处理出错:', err) return res.status(500).send('服务器内部错误') } })
额外注意事项
- 不要把密码对比结果作为查询条件传入
User.findOne,bcrypt哈希算法加盐后每次生成的结果不一致,这种查询方式永远查不到对应用户 - 建议增加try/catch捕获异步操作的异常,避免服务端崩溃
- 返回给前端的报错信息不要明确区分是用户名不存在还是密码错误,避免被恶意枚举系统用户
内容的提问来源于stack exchange,提问作者evan_tech1234
相关产品推荐
相关产品推荐

