I have read other post in StackOverflow about Bcrypt compare method returning false always. But I can not solve mine with the suggested answers. I am about to give up using Bcrypt. Could someone please point out what is wrong in my code. I am simply storing registration data with encrypted password in users array and after login attempt I am trying to compare the user-input password with the saved one in users array. No matter what I am doing the compare() method is returning false. PLease point out my mistake. I am providing the server.js file and passport.js file here.
The server.js -->
const express = require("express")
const bcrypt = require("bcrypt")
const initializePassport = require("./passport.js")
const flash = require("express-flash")
const session = require("express-session")
const { application } = require("express")
const passport = require("passport")
const server = express()
const users = []
const salt = bcrypt.genSaltSync(10);
initializePassport(
passport,
email => users.find(u => u.email === email),
id => users.find(u => u.id === id)
)
// below line of code is to get the form data in req.body
server.use(express.urlencoded({ extended: false }))
server.use(flash())
server.use(session({
secret: "1234",
resave: false, // we want to resave the session variable if nothing is changed
saveUninitialized: false
}))
server.use(passport.initialize())
server.use(passport.session())
async function main() {
const PORT = 8080
server.listen(PORT, function() {
console.log(`Server started on port ${PORT}...`)
})
}
server.get('/', async(req, res) => {
res.render("index.ejs")
})
server.get('/login', (req, res) => {
res.render('login.ejs')
})
server.post('/login', passport.authenticate("local", {
successRedirect: "/",
failureRedirect: "/login",
failureFlash: true
}))
server.get('/registration', (req, res) => {
res.render('registration.ejs')
})
server.post('/registration', async(req, res) => {
const { firstName, lastName, email, password } = req.body
await bcrypt.hash(password.toString(), salt)
.then((hashedPassword) => {
// Store the hashed password in the users array
users.push({
id: Date.now().toString(),
email: email,
password: hashedPassword,
firstName: firstName,
lastName: lastName
})
console.log(users)
res.redirect("/login")
})
.catch((error) => {
console.log(error);
});
})
main();
The passport.js file -->
const LocalStrategy = require("passport-local").Strategy
const bcrypt = require("bcrypt")
function initialize(passport, getUserByEmail, getUserById) {
// Function to authenticate users
const authenticateUsers = async(email, password, done) => {
// Get users by email
const user = await getUserByEmail(email)
console.log("THE Password BEFORE COMPARISON --> " password)
console.log(user)
if (user == null) {
console.log("user null;;;lllll")
return done(null, false, { message: "User is not registered" })
}
bcrypt.compare(password.toString().trim(), user.password, function(err, result) {
console.log("THE PASSWORD AFTER COMPARISON --> " password)
console.log(user)
if (err) {
console.log(err)
}
if (result == true) {
console.log("PASSWORD MATCHES")
} else {
console.log("DOESNOT MATCH")
}
})
}
passport.use(new LocalStrategy({ usernameField: 'email' }, authenticateUsers))
passport.serializeUser((user, done) => {
console.log(`---------------> Serialize User`)
console.log(user)
done(null, user.id)
})
passport.deserializeUser((id, done) => {
console.log("---------> Deserialize Id")
console.log(id)
return done(null, getUserById(id))
})
}
module.exports = initialize
And here is the registration view
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Registration</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP VmmDGMN5t9UJ0Z" crossorigin="anonymous">
<style>
.main {
background-color: #EAF7FF;
width: 100%;
height: 100vh;
margin: auto;
}
.form-container {
background-color: rgb(255, 255, 255);
max-width: 500px;
margin: 0 auto;
padding: 30px;
border: 1px solid #ccc;
border-radius: 10px;
box-shadow: 0 0 10px #ccc;
}
.btn {
background-color: #4F95FF;
border-radius: 14px;
}
</style>
</head>
<body>
<div >
<div >
<form action="/registration" method="POST">
<% if(messages.error) { %>
<div role="alert">
<strong><%= messages.error %></strong>
</div>
<% } %>
<h2 >Register</h2>
<div >
<input type="text" name="firstName" id="firstName" placeholder="First name">
</div>
<div >
<input type="text" name="lastName" id="lastName" placeholder="Last name">
</div>
<div >
<input type="email" name="email" id="email" placeholder="Email">
</div>
<div >
<input type="password" name="password" id="password" placeholder="Password">
</div>
<div >
<input type="password" name="password" id="password" placeholder="Confirm Password">
</div>
<div >
<button type="submit" >Create Account</button>
</div>
<div >
<p>Already have an account?
<a href="login">Login</p>
</div>
</form>
</div>
</div>
</body>
</html>
CodePudding user response:
Actually I found the issue. Its in frontend. I used same "name" and "id" attribute for password and confirmPassword field. So req.body.password was appending password from both field.