ExpressJS登录验证错误:comparePassword不是函数



backend/controllers文件夹中,我有一个authController类,它用电子邮件和密码处理POST请求,然后在数据库中用匹配的电子邮件查找用户,然后当它找到该用户时,它试图通过调用一个名为comparePassword的方法来验证密码,该方法在backend/models中的user类中定义。

authController类:

const User = require('../models/user');
const ErrorHandler = require('../utils/errorHandler');
const catchAsynErrors = require('../middlewares/catchAsyncErrors');
const sendToken = require('../utils/jwtToken');

// register user => /api/v1/register
exports.registerUser = catchAsynErrors(async (req, res, next)=> {
const { name, email, password} = req.body;
const user = await User.create({
name,
email, 
password,
avatar: {
public_id: '',
url: ''
}
})
sendToken(user, 200, res)
})

// login user => /a[i/v1/login
exports.loginUser = catchAsynErrors(async(req, res, next)=> {
const { email, password} = req.body;
// checks if email  and password is entered by the user
if(!email || !password){
return next(new ErrorHandler('Please enter email & password', 400))
}
//finding user in database
const user = await User.find( { email } ).select('+password')
if(!user){
return next(new ErrorHandler('Invalid Email or Password', 401))
}

// Attempting to print the user object's functions
console.log(user.comparePassword); // undefined
console.log(user.find); // [Function: find]

//checks if password is correct or not 
const isPasswordMatched = await user.comparePassword(password);

if(!isPasswordMatched){
return next(new ErrorHandler('Invalid Email or Password', 401))
}
sendToken(user, 200, res)   
});

用户类别:

const mongoose = require('mongoose');
const validator = require('validator');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const userSchema  = new mongoose.Schema({
name: {
type: String,
required: [true, 'Please enter your name'],
maxLenght: [30, 'Your name cannot exceed 30 characters']
},
email:{
type: String,
required: [true, 'Please enter your email'],
unique: true, 
validate: [validator.isEmail, 'Please enter a valid email address']
}, 
password:{
type: String,
required: [true, 'Please enter your password'],
minlenght: [6, 'Your password must have at least 6 characters'],
select: false
},
avatar:{
public_id: {
type: String,
required: true
},
url:{
type: String,
required: true
}
},
role:{
type: String,
default: 'user'
},
createdAt:{
type: Date,
default: Date.now
},
resetPasswordToken: String,
resetPasswordExpire: Date
})
//encrypting password before saving user
userSchema.pre('save', async function (next){
if(!this.isModified('password')){
next()
}
this.password = await  bcrypt.hash(this.password, 10)
})
// compare user password
userSchema.methods.comparePassword = async function (enteredPassword) {
return await bcrypt.compare(enteredPassword, this.password)
}

// return jwt token 
userSchema.methods.getJwtToken = function (){
return jwt.sign({ id: this._id }, process.env.JWT_SECRET, {
expiresIn: process.env.JWT_EXPIRES_TIME
});
}
module.exports = mongoose.model('User', userSchema);

这是我尝试用Postman发出POST请求时得到的结果以及控制台(在本例中,通过VS代码终端(在尝试console.log时显示的内容。将函数comparePassword与函数find一起记录,这两个函数都属于同一类。

邮差:

{
"success": false,
"error": {
"statusCode": 500
},
"errMessage": "user.comparePassword is not a function",
"stack": "TypeError: user.comparePassword is not a functionn    at D:\pruebas de programación\Proyectazo\backend\controllers\authController.js:47:42n    at processTicksAndRejections (node:internal/process/task_queues:96:5)"
}

控制台:

PS D:pruebas de programaciónProyectazo> npm run dev
npm WARN config global `--global`, `--local` are deprecated. Use `--location=global` instead.
> proyectazo@1.0.0 dev
> SET NODE_ENV=DEVELOPMENT& nodemon backend/server
[nodemon] 2.0.19
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json  
[nodemon] starting `node backend/server.js` 
Server started on PORT: 4000 in DEVELOPMENT mode. 
MongoDB Database connected with HOST: localhost
undefined
[Function: find]

我已经完成了这篇教程https://www.youtube.com/watch?v=_zXBZS6E-jM&list=PLkVd4_IMjZgkwcXwnpy7tenGNBbRdiRO8&index=27,并且它在视频中似乎完美地工作。我查找了其他解决方案,其中一些甚至在StackOverflow中,它们看起来都像是我拥有的相同实现的变体或重构。有什么想法吗?

提前感谢!

它不工作的原因是在loginUser函数中

//finding user in database
const user = await User.find( { email } ).select('+password')

user是一个数组。请改用use.findOne((方法

// This will return single user object
const user = await User.findOne( { email } ).select('+password')

最新更新