Password hash is working and its storing correctly
But while comparing the res is always returning false
Even though the password is correct. I am using bcryptjs for hashing
app.post("/api/register", (req, res) => {
const { name, email, school, phone, password } = req.body;
bcrypt.genSalt(10, function (err, salt) {
bcrypt.hash(password, salt, function (err, hash) {
con.query(
`INSERT INTO users(uid, u_name, u_email, u_school, u_phone, u_password) VALUES ('[value-1]','${name}','${email}','${school}','${phone}','${hash}')`,
function (err, result) {
if (err) {
console.log(err);
}
console.log(result);
}
);
});
});
});
app.post("/api/login", (req, res) => {
const { email, password } = req.body;
con.query(
`SELECT * FROM users WHERE u_email='${email}'`,
function (err, result) {
if (err) {
res.send(err.sqlMessage).end();
} else {
bcrypt.compare(password, result[0].u_password).then((res) => {
console.log(res);
});
}
}
);
});
You need to hash the password variable before you compare it in the login route. Otherwise you're comparing a hash and a string and those do not mix.
Thanks for the response.
I found the mistake it was in my database.
I limit my password varchar(30) but the string size was 60 thats why it was not working
Related
app.post('/addUsername', (req, res)=> {
const username = req.body.username;
db.query("SELECT * FROM userbase WHERE username = ?"), [username], (err, result)
if(result == username)
{
db.query("INSERT INTO userbase (username) VALUE (?)", [], (err, result)=> {
console.log(err);
})
}
else{
db.query("INSERT INTO userbase (username) VALUE (?)", [username], (err, result)=>
{
console.log(err);
})
}
})
I was trying to make it so if the username exist it would not send data to the database. but I dont think I structured this correctly. Basically this database is a big list full of usernames.
I have an API call that requires some information to be fetched from MySQL database in order to fulfill the request. The problem is, NodeJS won't wait for query response and I have tried to solve this with Promises. Here is my code:
app.post('/placeOrder', async function (req, res) {
console.log(req.body.orderInfo);
var username = decryptAccessToken(req.body.AuthToken);
console.log(username);
var firstQuery = await fetchCustomerInfo(username, req.body.orderInfo);
con.query("INSERT INTO Orders SET ?", firstQuery, function (err, response) {
if (!err) {
console.log("Order successfully placed");
res.send("Order successfully placed");
} else {
console.log(err);
}
});
});
async function fetchCustomerInfo(username, orderInfo) {
return new Promise((resolve, reject) => {
con.query("SELECT FirstName, LastName, Address, Email, Phone FROM Customers WHERE Email=?", username, function (err, response) {
var createOrder = {
FirstName: response.FirstName,
LastName: response.LastName,
Address: response.Address,
Email: response.Email,
Phone: response.Phone,
ProductInfoJSON: orderInfo
}
console.log(createOrder);
resolve(createOrder);
})
})
}
This fetchCustomerInfo function will just return Promise object and that will trigger SQL syntax error, because that is not expected database input. What I'm doing wrong? Any advise is highly appreciated.
Update: SQL error has been solved with Murat's answer, but database query still returns undefined. I have made sure that the query works in console when used manually.
Try this:
app.post('/placeOrder', async function (req, res) {
var username = decryptAccessToken(req.body.AuthToken);
console.log(username);
var firstQuery = await fetchCustomerInfo(username, req.body.orderInfo);
con.query("INSERT INTO Orders SET ?", firstQuery, function (err, response) {
if (!err) {
console.log("Order successfully placed");
res.status(200).send("Order successfully placed");
} else {
console.log(err);
res.status(500).send("Error!");
}
});
});
function fetchCustomerInfo(username, orderInfo) {
return new Promise((resolve, reject) => {
con.query("SELECT FirstName, LastName, Address, Email, Phone FROM Customers WHERE Email=?", username, function (err, response) {
var createOrder = {
FirstName: response.FirstName,
LastName: response.LastName,
Address: response.Address,
Email: response.Email,
Phone: response.Phone,
ProductInfoJSON: orderInfo
}
console.log(createOrder);
resolve(createOrder);
})
})
}
Edit:
Since I have not had much experience with the MySql library, I did not check the accuracy of the function while writing the answer. However, the way you use con.query() is wrong. If you look at W3 Schools, this is the right way to use it.
var mysql = require('mysql');
var con = mysql.createConnection({
host: "localhost",
user: "yourusername",
password: "yourpassword",
database: "mydb"
});
con.connect(function(err) {
if (err) throw err;
con.query("SELECT * FROM customers", function (err, result, fields) {
if (err) throw err;
console.log(result);
});
});
I have a problem in comparing method of bcrypt. This mthod is not able to compare password properly. Please sort out me from this problem.There is problem with comparing method its not working.I have a problem in comparing method of bcrypt. This mthod is not able to compare password properly. Please sort out me from this problem.There is problem with comparing method its not working.
app.post('/upload', (req, res) => {
// hash and save a password
const pass = bcrypt.hashSync(req.body.password);
const username = req.body.username;
console.log(bcrypt.compareSync(req.body.password, pass));
const sql = "INSERT INTO data ( password, username ) values (?,?)";
db.query(sql, [pass, username], (err, rows, fields) => {
if(!err){
res.send({
key: rows
});
}
else {
console.log(err);
}
});
})
app.post('/show', (req, res) => {
const username = req.body.username;
const password = req.body.password;
db.query("SELECT * FROM data WHERE username = ?",[username], function(err, results){
if (err) {
// console.log("error ocurred",error);
res.send({
"code":400,
"failed":"err ocurred"
})
}else{
if(results.length >0){
// console.log(bcrypt.compareSync(password, results[0].password));
if(bcrypt.compareSync(password, results[0].password)){
res.send({
"code":200,
"success":"login sucessfull"
});
}
else{
res.send({
"code":204,
"success":"Email and password does not match"
});
}
}else{
res.send({
"code":204,
"success":"Email does not exits"
});
console.log(results.length);
}
}
})
})
I am using node, mysql as the server and DB and ionic on the front end. I've managed to register a user with a hash using bcrypt and attempting to authenticate the user to log them in.
When comparing the password that user enters, in bcryptJS it seems like we cannot decrypt their password. When I console.log password and the result of user lookup in my db, I am comparing the password that the user enters with the hash that's stored so i am always retuning a 400 status to the front end.
Authentication code:
app.post('/login', function(req, res) {
connection.connect(function(err) {
let email = req.body.email;
let password = req.body.password;
connection.query("SELECT * FROM sometable WHERE username = ? ", [email], function(error, results, fields) {
bcrypt.compare(req.body.password, results[0].password, function(err, result) {
console.log('>>>>>> ', password)
console.log('>>>>>> ', results[0].password)
if(result) {
return res.send();
}
else {
return res.status(400).send();
}
})
});
});
});
What's the proper way to compare the password user enters with the hash that's stored in my db?
Thanks for your help.
edit:
I've tried the below code (adding a password strings) and I'm still getting the false result... What am I missing here?
bcrypt.compare('somePassword', 'somePassword', function(err, res) {
if(res) {
console.log('true')
} else {
console.log('false')
}
});
Check to ensure you have the password before doing the comparison to know if the passwords match.
see my modification below
app.post('/login', function(req, res) {
connection.connect(function(err) {
let email = req.body.email;
let password = req.body.password;
connection.query("SELECT * FROM sometable WHERE username = ? ", [email], function(error, results, fields) {
if (results[0].password) {
bcrypt.compare(req.body.password, results[0].password, function(err, result) {
console.log('>>>>>> ', password)
console.log('>>>>>> ', results[0].password)
if(result) {
return res.send();
}
else {
return res.status(400).send();
}
})
}
});
});
});
So, as discussed in the comments of the question, the issue turned out to be the format of the column used to store the hashed password.
If you set your column to char(50) for instance, some databases will just silently remove anything beyond 50 chars, or add spaces to get to 50 chars if you have less.
This then breaks the comparison with the hashed version.
app.post('/login', function(req, res) {
connection.connect(function(err) {
let email = req.body.email;
let password = req.body.password;
connection.query("SELECT * FROM sometable WHERE username = ? ", [email], function(error, results, fields) {
if(error) throw error;
else {
if(results.length > 0) {
bcrypt.compare(req.body.password, results[0].password, function(err, result) {
if(result) {
return res.send({ message: "Login Successful" });
}
else {
return res.status(400).send({ message: "Invalid Password" });
}
});
} else {
return res.status(400).send({ message: "Invalid Email" });
}
}
});
});
});
Sorry guys! i had the some proble nut it was comming from mysql it was because i had a column callded password which was in CHAR(50) so if the hash is long than to 50 char it was truncating it, whyle hashed password are very long so i have changed the field from CHAR(50) to VARCHAR(255);
Then everything start work fine
I'm fairly new to nodejs and callbacks. Here is my problem, using passportJS's LocalStrategy and node-mysql :
exports.register = new LocalStrategy(strategyOptionsRegister, function(req, username, password, done) {
//get data from the request
var data = {
username: username,
email: req.body.email,
password: password
};
console.log('data : ', data);
//Hash passwords
bcrypt.genSalt(10, function(err, salt) {
if (err) return next(err);
bcrypt.hash(password, salt, null, function(err, hash) {
// Store hash in your password DB.
if (err) return next(err);
data.password = hash;
//insertion
connection.query('INSERT INTO USERS SET ?', data, function(err, rows) {
if (err) {
console.log(err);
return next("Mysql error, check your query");
}
return done(null, rows[0]);
});
});
});
});
I'm trying to return rows[0] containing all the data, but i don't know how should i implement the SELECT command ? Is it before or after the callback for the insertion ? For the moment, rows[0] is naturally undefined.
what about using async.waterfall?
I solve similar problem.
insert query
get auto_incremnet number from rows[0]
select query
website of async here
https://github.com/caolan/async#waterfall
Also, as bcrypt is asyncronous,
data,password = hash
this code doesn't work properly.
I want to execute same type of code for yours but I can't.
So, I use bcrypt in Sync and pass the hash to query.
Here is my solution :
exports.register = new LocalStrategy(strategyOptionsRegister, function(req, username, password, done) {
//get data from the request
var data = {
username: username,
email: req.body.email,
password: password
};
//Hash passwords
bcrypt.genSalt(10, function(err, salt) {
if (err) {
return done(err);
}
// Store hash in your password DB.
bcrypt.hash(password, salt, null, function(err, hash) {
if (err) {
return done(err);
}
data.password = hash;
//insertion
connection.query('INSERT INTO USERS SET ?', data, function(err, rows) {
if (err) {
return done(null, false, {
message: 'Mysql error, check your query !'
});
}
// to return all the info in rows[0]
connection.query('SELECT * FROM USERS WHERE email = ?', data.email, function(err, rows) {
if (err) {
return done(null, false, {
message: 'Email not found !'
});
}
return done(null, rows[0]);
});
});
});
});
});