Reputation: 87
I'm having problem in comparing the password and yes it is storing the hash of the password correctly when I'm registering.
Database - MongoDB I'm using node.js version - v18.17.0 bcrypt version - 5.1.1
Here's my userSchema -
const userSchema = new mongoose.Schema({
username: { type: String, required: true, unique: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
});
userSchema.pre('save', async function (next) {
try {
if (!this.isModified('password')) {
return next();
}
const hashedPassword = await bcrypt.hash(this.password, 10);
this.password = hashedPassword;
return next();
} catch (error) {
...
}
})
also here's my AuthController.js file's login part -
loginUser: async (req, res) => {
try {
const { email, password } = req.body;
const user = await User.findOne({ email });
if (!user) {
return res.status(401).json({ error: 'Invalid email or password.' });
}
const trimmedPassword = password.trim();
console.log('Password received:', password);
console.log('User password:', user.password);
const passwordMatch = await bcrypt.compare(trimmedPassword, user.password);
console.log(passwordMatch);
if (!passwordMatch) {
return res.status(401).json({ error: 'Invalid email or password.' });
}
// Generate a JWT token
const token = jwt.sign({ userId: user._id }, process.env.JWT_SECRET, { expireIn: '1h' });
res.json({ token, userId: user._id, username: user.username });
} catch(error){...}
I'm using postman right now to check it, postman giving me error: 'Invalid email or password', and in the terminal i'm getting -
Password received: abcd
User password: $2b$10$3XqxT29oUNX8Sr86i/woPufzHf6s7OjP4yyNdirtGk9Zj0T3MdkAC
false
Upvotes: 1
Views: 449
Reputation: 1
LoginUser = async (req, res) => {
let success = false;
// 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) {
success = false
return res.status(400).json({ error: "Please try to login with correct credentials" });
}
const passwordCompare = await bcrypt.compare(password, user.password);
if (!passwordCompare) {
success = false
return res.status(400).json({ success, error: "Please try to login with correct credentials" });
}
const data = {
user: {
id: user.id
}
}
// console.log("hello "+ data.user.id)
const authtoken = jwt.sign(data, process.env.JWT_SECRET);
success = true;
res.json({ success, authtoken })
} catch (error) {
console.error(error.message);
res.status(500).send("Internal Server Error");
}
}
Upvotes: -1
Reputation: 1
loginUser: async (req, res) => {
try {
const { email, password } = req.body;
const user = await UserModel.findOne({ email: email });
if (!user) {
return res.status(401).json({ error: 'Invalid email or password.' });
}
const trimmedPassword = password.trim();
console.log('Password received:', password);
console.log('User password:', user.password);
const passwordMatch = await bcrypt.compare(trimmedPassword, user.password);
console.log(passwordMatch);
if (!passwordMatch) {
return res.status(401).json({ error: 'Invalid email or password.' });
}
const token = jwt.sign({ userId: user._id }, process.env.JWT_SECRET, { expiresIn: '1h' });
res.json({ token, userId: user._id, username: user.username });
} catch(error) {
console.error(error);
res.status(500).json({ error: 'An error occurred during the login process.' });
}
}
Upvotes: -1
Reputation: 87
Thanks to @Savyon, I think I was hashing the password twice so I removed the hashing process from the register code part and made these changes on my user model code -
userSchema.pre('save', async function (next) {
try {
if (!this.isModified('password') || this.isModified('password') && typeof this.password === 'string') {
const hashedPassword = await bcrypt.hash(this.password, 10);
this.password = hashedPassword;
}
return next();
} catch (error) {
return next(error);
}
})
Upvotes: 0
Reputation: 71
instead of comparing directly inside AuthController.js
you can make sure youre accessing the right user by adding a method directly to User model (also make sure bcrypt is imported):
userSchema.methods.comparePassword = function (candidatePassword) {
return bcrypt.compareSync(candidatePassword, this.password);
};
once you have relevant user inside AuthController.js
:
const isPasswordVerified = user.comparePassword(payload.password);
Upvotes: 2