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

登录接口bcrypt.compare报错:参数非法/参数缺失

登录接口bcrypt验证报错排查与解决

问题现象

开发登录接口生成Auth Token时,创建用户接口可正常运行,但发起登录认证请求时返回内部服务器错误,切换bcryptjs和bcrypt库均出现参数相关报错。

报错信息

使用bcryptjs时的报错

Illegal arguments: string, undefined
[nodemon] restarting due to changes...
[nodemon] starting `node server.js index.js`
    at _async (D:\Web Development\REACT PROJECTS\inotebook\backend\node_modules\bcryptjs\dist\bcrypt.js:286:46)
    at D:\Web Development\REACT PROJECTS\inotebook\backend\node_modules\bcryptjs\dist\bcrypt.js:307:17
    at new Promise (<anonymous>)
    at Object.bcrypt.compare (D:\Web Development\REACT PROJECTS\inotebook\backend\node_modules\bcryptjs\dist\bcrypt.js:306:20)
    at new Promise (<anonymous>)
    at Object.bcrypt.compare (D:\Web Development\REACT PROJECTS\inotebook\backend\node_modules\bcryptjs\dist\bcrypt.js:306:20)
    at D:\Web Development\REACT PROJECTS\inotebook\backend\routes\auth.js:73:42
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

替换为bcrypt库后的报错

Error: data and hash arguments required
    at Object.compare (D:\Web Development\REACT PROJECTS\inotebook\backend\node_modules\bcrypt\bcrypt.js:208:17)
    at D:\Web Development\REACT PROJECTS\inotebook\backend\node_modules\bcrypt\promises.js:29:12
    at new Promise (<anonymous>)
    at Object.module.exports.promise (D:\Web Development\REACT PROJECTS\inotebook\backend\node_modules\bcrypt\promises.js:20:12)
    at Object.compare (D:\Web Development\REACT PROJECTS\inotebook\backend\node_modules\bcrypt\bcrypt.js:204:25)
    at D:\Web Development\REACT PROJECTS\inotebook\backend\routes\auth.js:73:42
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

相关代码片段

报错集中在auth.js的bcrypt.compare调用处:

const {email, password} = req.body;
try {
  let user = await User.findOne({email});
  if(!user){
    return res.status(400).json({error: "Please try to login with correct credentials"});
  }

  const passwordCompare = await bcrypt.compare(password, user.password);
  if(!passwordCompare){
    return res.status(400).json({error: "Please try to login with correct credentials"});
  }

完整auth.js代码

const express = require('express');
const User = require('../models/User');
const router = express.Router();
const { body, validationResult } = require('express-validator');
const bcrypt = require('bcryptjs');
var jwt = require('jsonwebtoken');

const JWT_SECRET = 'usisagoodb$oy';

// Create a User using: POST "/api/auth/createuser". No login required
router.post('/createuser', [
  body('name', 'Enter a valid name').isLength({ min: 3 }),
  body('email', 'Enter a valid email').isEmail(),
  body('password', 'Password must be atleast 5 characters').isLength({ min: 5 }),
], async (req, res) => {
  // If there are errors, return Bad request and the errors
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({ errors: errors.array() });
  }
  try {
    // Check whether the user with this email exists already
    let user = await User.findOne({ email: req.body.email });
    if (user) {
      return res.status(400).json({ error: "Sorry a user with this email already exists" })
    }
    const salt = await bcrypt.genSalt(10);
    const secPass = await bcrypt.hash(req.body.password, salt);

    // Create a new user
    user = await User.create({
      name: req.body.name,
      password: secPass,
      email: req.body.email,
    });
    const data = {
      user:{
        id: user.id
      }
    }
    const authtoken = jwt.sign(data, JWT_SECRET);
    
    // res.json(user)
    res.json({authtoken})
    
  } catch (error) {
    console.error(error.message);
    res.status(500).send("Internal Server Error");
  }
})


// Authenticate a User using: POST "/api/auth/login". No login required
router.post('/login', [ 
  body('email', 'Enter a valid email').isEmail(), 
  body('password', 'Password cannot be blank').exists(), 
], async (req, res) => {

  // If there are errors, return Bad request and the errors
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({ errors: errors.array() });
  }

  const {email, password} = req.body;
  try {
    let user = await User.findOne({email});
    if(!user){
      return res.status(400).json({error: "Please try to login with correct credentials"});
    }

    const passwordCompare = await bcrypt.compare(password, user.password);
    if(!passwordCompare){
      return res.status(400).json({error: "Please try to login with correct credentials"});
    }

    const data = {
      user:{
        id: user.id
      }
    }
    const authtoken = jwt.sign(data, JWT_SECRET);
    res.json({authtoken})

  } catch (error) {
    console.error(error);
    res.status(500).send("Internal Server Error");
  }
})
module.exports = router

问题分析与解决

两个库的报错核心都是bcrypt.compare的参数缺失或非法:bcrypt.compare(password, user.password)中,要么password为undefined,要么user.password为undefined。

结合代码来看,创建用户时已正确加密并存储密码,所以大概率是查询用户时未返回password字段,原因可能有两种:

  1. User模型Schema未定义password字段:Mongoose不会存储未在Schema中声明的字段,导致数据库中没有password数据。
  2. Schema中password设置了select: false:该配置会让Mongoose默认查询时不返回password字段。

解决步骤

  1. 检查User模型Schema:确保包含password字段,示例如下:
const mongoose = require('mongoose');
const UserSchema = new mongoose.Schema({
  name: { type: String, required: true },
  email: { type: String, required: true, unique: true },
  password: { type: String, required: true } // 必须声明该字段
});
module.exports = mongoose.model('User', UserSchema);
  1. 如果Schema中password设置了select: false:在登录查询时显式指定返回password字段:
// 将原查询代码修改为
let user = await User.findOne({email}).select("+password");
  1. 临时调试验证:在bcrypt.compare前添加打印语句,确认参数是否存在:
console.log("Request password:", password);
console.log("User password from DB:", user.password);

内容的提问来源于stack exchange,提问作者Upmanyu Sharma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 17:20:26