在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')