I am making a login route with mongoose
and express
. When I create an account, the password is hashed by bcrypt
. When I log in, I need to compare them. So here is my try :
const mongoose = require("mongoose");
const bcrypt = require("bcrypt");
const UserSchema = new mongoose.Schema(
{
email: {
type: String,
required: [true, "L'e-mail est requis"],
unique: true
},
password: {
type: String,
required: [true, "Le mot de passe est requis"]
},
firstname: {
type: String,
required: [true, "Le prénom est requis"]
},
lastname: {
type: String,
required: [true, "Le nom est requis"]
}
},
{ collection: "users" }
);
UserSchema.pre("save", async function(next) {
const user = this;
const salt = await bcrypt.genSalt(10);
const hash = await bcrypt.hash(user.password, salt);
user.password = hash;
next();
});
UserSchema.methods.isValidPassword = async function(password) {
const user = this;
const compare = await bcrypt.compare(password, user.password);
return compare;
};
module.exports = mongoose.model("User", UserSchema);
The problem is, my route returns "Wrong password". Here is the controller :
module.exports.signIn = async (req, res) => {
const { email, password } = req.body;
const user = await UserModel.findOne({ email });
if (!user) {
return res.status(400).json({
message: "email not found."
});
}
if (user.password !== password) {
return res.status(400).json({
message: "wrong password."
});
}
res.status(200).json({
message: "User signed in."
});
};
It is like my request doesn't go by UserSchema.methods.isValidPassword
. Any idea why ?
CodePudding user response:
This block:
if (user.password !== password) {
return res.status(400).json({
message: "wrong password."
});
}
just compare the password in the request with the hash password stored in your database. The condition is true so you have the message "wrong password".
You need to call the method isValidPassword
explicitly.
const isValidPassword = await user.isValidPassword(password);
if (!isValidPassword) {
return res.status(400).json({
message: "wrong password."
});
}
Quick side note: You shouldn't have 2 different messages for email not found and the wrong password. This allows users to know if the email exists and execute a brute force attack. I suggest something like "Email or password is incorrect" instead.