错误:非法参数:字符串,未定义,并停止node JS服务器

8

我正在尝试在Node JS中构建日志记录应用程序。在这里,密码认证应用程序无法正常工作。当我输入用户名和密码时,它会出现以下错误并停止服务器。

this is the error.

enter image description here

Here is the code for authentication part

passport.use(new LocalStrategy(
function(username, password, done) {
    User.getUserByUsername(username, function(err, user){
       if(err) throw err;
       if (!user) {
           return done(null, false, {message: 'Unknown user'});
       } 

       User.comparePassword(password, user.password, function(err, isMatch){
           if(err) throw err;
           if (isMatch) {
               return done(null, user);
           } else {
               return done(null, false, {message: 'Invalid password'});
           }
       });
    });
}));

这段代码可以给未知用户使用,但是无法用来比较用户名和密码。我在这里看不到任何错误。我希望能得到帮助来解决这个问题。


3
当调用.comparePassword()时,passworduser.password的值是什么?看起来它抱怨user.passwordundefined - Pointy
"password" 是用户登录时输入的值。"user.password" 是存储在数据库中的值。根据用户名,它指的是密码,并将其与用户输入的值进行比较。 - Buddhika Priyabhashana
好的。user.password 的值是多少? - Pointy
我找到了问题所在。数据库中存储了相同的用户名,这就是为什么会出现错误的原因。因为这将成为验证和比较密码的问题。因为它必须将相同的用户名与许多密码进行比较。我也应该验证它。谢谢您的关注。 - Buddhika Priyabhashana
10个回答

4

以宇宙程序员之名

在我的情况下,我忘记选择密码,因为在数据库中密码是 ((select: false))

这段代码是用于应用程序的

const user = await User.findOne({email}).select("+password")

我忘记在findOne后添加((.select("+password"))),导致出现以下错误信息:

Error: Illegal arguments: string, undefined

下面是数据库的代码:

const User = new mongoose.Schema({
    username:{
        type:String,
        required: [true,"نام کاربری ضروری است"]
    },
    email:{
        type:String,
        required: [true,"رایانامه ضروری است"],
        unique: true,
        match:[
            /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{1,3})$/,
            "لطفا یک رایانامه صحیح وارد کنید"
        ]
    },
    password:{
        type:String,
        required:[true,"رمز ضروری است"],
        minlegth: 5,
        select: false
    }
})

.select("+password") 对我有用,因为在我的 User 模型中,密码是 select:false。谢谢。 - AllisLove

2
我在这里找到了问题,它与代码无关。事情是我注册了两个使用相同用户名但不同密码的用户。当我尝试使用该用户名和一个密码登录时,就会出现此错误并停止服务器。
因为要查找用户输入的用户名的密码有尴尬的情况。因为有两个具有相同用户名的密码。

你是如何解决那个问题的? - Adrian Gheorghe

1
在我的情况下,我使用了箭头函数。
userSchema.methods.comparePassword = async (enterdPassword) => {
  return await bcrypt.compare(enterdPassword, this.password);
};

我将其转换为普通函数。

userSchema.methods.comparePassword = async function (enterdPassword) {
  return await bcrypt.compare(enterdPassword, this.password);
};

那解决了问题


0

你需要在盐和密码的赋值中也应用await。

就像这样:

const salt = await bcrypt.genSaltSync(10);
const password = await req.body.password;

0
你可以编写这样的代码:在 this.findOne({ select: [] ........}) 后面...希望这对你有所帮助。

async validateUserPassword(loginDto: AuthLoginDto): Promise<User> {
    const { mobile, email, password } = loginDto;
    const user = await this.findOne({
      select: ['id', 'email', 'mobile', 'password', 'salt', 'status', 'logged_at'],
      where: [
        { mobile: mobile },
        { email: email }
      ]

    });

    if (user && await user.validatePassword(password)) {
      const logged_at = {
        logged_at: new Date()
      }
      await this.update({ id: user.id }, logged_at)
      return user;
    } else {
      return null;
    }
  }
  
  async validatePassword(password: string): Promise<boolean> {
    const hash = await bcrypt.hash(password, this.salt);
    return hash === this.password;
  }


0

"models/user.js"

在 comparePassword 函数内部

module.exports.comparePassword = (candidatePassword, hash, callback) => {...) 

添加以下代码:

bcrypt.hash(candidatePassword, 10, (err, hash) => {
    if(err) {
        throw err;
    }
    bcrypt.compare(candidatePassword, hash, (err, isMatch) => {
        if(err) {
            throw err;
        }
        callback(null, isMatch);
    });
});

0
在我的情况下,我只想检查旧密码是否与数据库中的密码匹配,但是出现了错误,以下是我的代码:
changePassword = asyncHandler (async (req: IGetUserAuthInfoRequest, res: Response) => {
  const user = await User.findById(req.user._id)
  const {oldPassword, password} = req.body

  if(!user) {
    res.status(400)
    throw new Error("User not found, please signup")
  }

  // Validate
  if(!oldPassword || !password) {
    res.status(400)
    throw new Error("Please add old and new password")
  }

  // Check if old password matches password in DB
  const passwordIsCorrect = await bcrypt.compare(oldPassword, user.password)

  // Save new password
  if(user && passwordIsCorrect) {
    user.password = password
    await user.save()
    res.status(200).send("Password change successful")
  } else {
    res.status(400)
    throw new Error("Old password is incorrect")
  }

});

1
如果这是一个问题,请将其作为新问题发布,而不是回答现有问题。干杯。 - farshad
我修正了它,我在获取用户ID时添加了".select("+password")"。 - Emmanuel Igwesi

0
在我的情况下,我正在使用社交登录/注册。当用户使用社交登录选项进行注册时,存储的密码值为“NULL”。
因此,我只是添加了这个小检查:
  comparePassword: function(password, user){
    if (!user.password)
      return false;
    return bcrypt.compareSync(password, user.password);
  }

0

在这里,我们从登录页面获取用户名和密码,并通过数据库查找我们的用户,然后将其加密密码与用户输入的密码进行匹配。

passport.use(new LocalStrategy(
    (username,password,done)=> {
        db.users.findOne({username: username},(err, user)=> {
            if(err) return done(err);

            if(!user) {
                return done(null,false,{message: 'Incorrect Username'});
            }
            bcrypt.compare(password, user.password,(err,isMatch)=> {
                if(err) return done(err);
                if(isMatch) {
                    return done(null, user);
                } else {
                    return done(null, false,{message: 'Incorrect Password'});
                }
            });
         });
      }
   ));

0

对于我的情况,在编写连接数据库并查找密码的代码时,我没有使用 "await" 关键字,因此我得到了相同的错误。

router.post("/login", async function (req, res) {

  const userdata = req.body;
  const enteredEmail = userdata.email;
  const enteredPassword = userdata.password;

  const existingUser =await db
      .getDb()
      .collection("users")
      .findOne({ email: enteredEmail });

  if (!existingUser) {
    console.log('Could not log in!')
    return res.redirect('/login')
  }

  const passwordsAreEqual = await bcrypt.compare(enteredPassword, 
existingUser.password);

  if (!passwordsAreEqual) {
    console.log("Could not log in! Incorrect Password");
    return res.render('/login')

  }
  console.log('User is authenticated');
  res.redirect('/admin');
  });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接