How to add session and add access token to login in node - mysql

I have a login api as follows :
app.post('/login', function (req, res){
email = req.body.email;
password = req.body.password;
if(email && password )
{
console.log(email); //displays the email in the terminal
console.log(password); //displays the password in the terminal
var status = []; //array to output json
//connection.connect(); //mysql connection
connection.query('SELECT username FROM user WHERE email =? and password = ?',[email,password], function (error, rows, fields) {
if(rows.length == 1)
{
passport.serializeUser(function(res, done) {
done(null,res);
});
passport.deserializeUser(function(id, done) {
done(null,res);
});
status.push({username: rows[0].username});
username = rows[0].username;
console.log('sucessful login');
res.end('"status:"\n'+JSON.stringify(status)); //output as JSON
}
if(rows.length == 0)
{
connection.query('select * from temp_users where email = ? and password = ?',[email,password],function(error,rows,fields)
{
status = '';
if(rows.length == 1)
{
status = 'pending';
//res.end('Your Account needs to be verified');
res.end('"status:"'+JSON.stringify(status));
console.log('Your Account needs to be verified.');
}
else
{
status = 'error';
res.end('"status:"'+JSON.stringify(status));
//res.end('no such user.Please create an account');
console.log('no such user.Please create an account');
}
}
);
}
});
}
});
Now what i would like to do is to add a session for every user that logs in and make that session expire after some time.I would also like to have an access token to be inserted to my database once the user logs in.
Any help?

This example does exactly what you are looking for.
node.js express mysql passport

Related

bcrypt nodejs - null error when trying to login with comparing hashed password from the database

I created a basic register and login page connected to local mysql - that collects email, username and password (password gets hashed with bcrypt) and stores them in database.
Yet when i am trying to log in I get an error that says just : null + (console log saying password + else2 so i know which line got called)
This is login.js file
exports.login = (req, res) => {
console.log(req.body);
let email = req.body.email;
let password = req.body.password;
let username = req.body.username;
//if it finds username and email matching login credentials it will check for password
db.query('SELECT username, email, password FROM users WHERE username = ? AND email = ?', [username, email], function (error, results) {
if (error) {
res.send({
"code": 400,
"failed": "error ocurred"
});
}
//results[0].password means the password of the user that was found.
// it should compare plain password with the encrypted password in database
//and redirect to the /profile page if the password are a match.
if (results.length > 0) {
bcrypt.compare(password, results[0].password, function (error, answer) {
if (error) {
console.log(password +'if1')
console.log("comparing gone wrong", error);
return res.render('login', {
message3: 'Comparing error - please try again later'
});
}
if (answer) {
console.log(password + 'if 2')
res.redirect("/profile");
console.log("login successfull!");
}
else {
console.log(password + ' else2', error)
return res.render('login', {
message3: 'User or password or email is wrong'
});
}
});
} else {
console.log(password + 'else3')
return res.render('login', {
message3: 'User or password or email is wrong'
});
}
});
};
I will also put the register.js file if that will help with anything.
exports.register = (req, res) => {
console.log(req.body);
const { username, email, password, passwordConfirm } = req.body;
db.query('SELECT email FROM users WHERE email = ?', [email], async (error, result) => {
if(error) {
console.log(error);
}
if( result.length > 0 ) {
return res.render('register', {
message: 'That email is already in use'
})
} else if( password !== passwordConfirm) {
return res.render('register', {
message: 'That passwords do not match'
});
}
let hashedPassword = await bcrypt.hash(password, 8);
console.log(hashedPassword);
db.query('INSERT INTO users SET ?', {username: username, email: email, password: hashedPassword }, (error, result) => {
if(error) {
console.log(error);
} else {
console.log(result);
return res.render('register', {
message2: 'User Registered!'
});
}
})
});
}
Well, now I know why finding an answer online was so hard.
The code is right, the problem was in my database, I previously allowed for 50 Varchar password (but hashing it makes it longer, and it was getting cut), after I changed it to 128 chars it works perfectly with the new users that now register and login under the new broader restrictions.

Retrieving hashed password from sql database

Having issues comparing user password and hashed password using bcrypt.I'll be glad if anyone helps.
Here is my login code snippet
app.post('/login', (req, res) => {
const username = req.body.username;
const password = req.body.password;
const searchSql2 = 'SELECT * FROM users WHERE user_name = ?'
con.query(searchSql2,[username], async(err, results,fields) => {
if (err) throw err;
const hashedPassword = results[0].user_password
const isValid = bcrypt.compareSync(password, hashedPassword)
if (isValid) {
//password matched
req.session.loggedin = true;
req.session.username = username;
res.redirect('./home')
res.end();
} else {
res.send("Invalid username or password")
}
})
})
When user logins even with correct details he/she gets 'Invalid username or password!'.How do I go about this?

Bycrpt cannot compare and always sends null values

i m using Bycrpty library for security. so i read bycrpt Official document.
i sent postman in signup routes. it work or not
it was success full! like that.
so i have to compare the passwords When logging in,
but compare is always failed. it's my code..
const jwt = require('jsonwebtoken');
// const { Op } = require("sequelize");
const { user } = require("../../models");
const bcrypt = require("bcrypt");
const salt = bcrypt.genSaltSync(10) ;
signUpController: async (req, res) => {
const { username, email, password} = req.body;
if( !(username && email && password) ){
res.status(405).send({
"message" : "invalid request"
});
}
else{
const userInfo = await user.findOne({
where: {
email: email,
username : username
}
});
if(userInfo === null){
const newUser = await user.create({
username: username,
email : email,
password: bcrypt.hashSync(password, salt),
});
let response = {
username: newUser.username,
email: newUser.email,
username: newUser.username,
password : newUser.password
}
res.status(201).json( response );
}
else{
res.status(409).send({
"message" : "email already exist"
});
}
}
},
login : async(req,res)=>{
const { email, password } = req.body;
const userInfo = await user.findOne({
where: {
email: email,
password : password
}
});
// console.log("req: ", req)
if(!userInfo) {
await res.status(400).send({data : null, message : 'not authorized'})
}
else {
const data = {...userInfo.dataValues}
console.log('password:', checkMail.password)
bcrypt.compareSync(password, userInfo.password) ;
delete data.password
const accessToken = jwt.sign(data, process.env.ACCESS_SECRET, {expiresIn : '3h'}) // create jwt
const refreshToken = jwt.sign(data, process.env.REFRESH_SECRET, {expiresIn : '1h'}) // save in cookie .
res.cookie("refreshToken", refreshToken)
res.status(200).send({data:{"accessToken": accessToken}, message:'ok'})
}
}
What should I do to be successful? I need advice and tips.
I'm slightly confused as your using async/await for some things like the database library however not for bcrypt which also has promises and instead you're using their sync versions. As a first advice I wouldn't use the sync versions of the code as they block the eventLoop.
There is another problem with your logic - which is highlighted below.
const jwt = require('jsonwebtoken');
// const { Op } = require("sequelize");
const { user } = require("../../models");
const bcrypt = require("bcrypt");
const salt = bcrypt.genSaltSync(10) ;
signUpController: async (req, res) => {
const { username, email, password} = req.body;
if( !(username && email && password) ){
res.status(405).send({
"message" : "invalid request"
});
}
else{
const userInfo = await user.findOne({
where: {
email: email,
username : username
}
});
// using email/username as unique fields to find a user and check if they already have an account
if(userInfo === null){
const newUser = await user.create({
username: username,
email : email,
password: bcrypt.hashSync(password, salt),
// saving the hashed password rather than the plaintext password
});
let response = {
username: newUser.username,
email: newUser.email,
username: newUser.username,
password : newUser.password
}
// do not under any circumstance send the password back to the user.
res.status(201).json( response );
}
else{
res.status(409).send({
"message" : "email already exist"
});
}
}
},
login : async(req,res)=>{
const { email, password } = req.body;
// you're trying to find a user that exists based on their email and plaintext password, but the password you've saved is the HASHED version not the plaintext version so this result will always be empty... No such user exists
const userInfo = await user.findOne({
where: {
email: email,
password : password
}
});
// console.log("req: ", req)
if(!userInfo) {
// hence this error is present ALL THE TIME
await res.status(400).send({data : null, message : 'not authorized'})
}
else {
const data = {...userInfo.dataValues}
console.log('password:', checkMail.password)
bcrypt.compareSync(password, userInfo.password) ;
// you wouldn't need this step as you've found the user based on the password
delete data.password
const accessToken = jwt.sign(data, process.env.ACCESS_SECRET, {expiresIn : '3h'}) // create jwt
const refreshToken = jwt.sign(data, process.env.REFRESH_SECRET, {expiresIn : '1h'}) // save in cookie .
res.cookie("refreshToken", refreshToken)
res.status(200).send({data:{"accessToken": accessToken}, message:'ok'})
}
}
This seems to me rather than misunderstanding how password hashing works you don't understand the data in your database.
I'd suggest to get a visual database explorer for whatever database you're trying to use. There are many free and opensource ones out there!

How to show data on frontend using Controller in Mysql

I am trying to show data on front end using controller in Angular js but unable to do so I am able to take data from database that is mysql but don't know how to show it on frontend
module.exports = function(app) {
app.post('/login', function(req, res) {
var email = req.body.email;
var password = req.body.password;
console.log(password);
if (email && password) {
connection.query('select * from user where email = ? and password = ?', [email, password], function(err, result) {
console.log(result);
if (err) res.send(err);
res.redirect('/dashboard');
});
}
});
}

bcrypt issue using nodejs

I have successfully encrypted the password and stored in my DB during registration. But when I am login, I am comparing the password and trying to login, during the login period my sql query is falling to read the password and I am getting hash is not defined. Please let me know where I am going wrong.
router.post('/login', function(req,res) {
var password = req.body.password;
var user_name = req.body.user_name;
var response = {};
bcrypt.compare(password, hash, function(err, res) {
db.query('select user_id,email FROM user where password = ? AND user_name = ? OR email = ?',
[hash, req.body.user_name, req.body.user_name], function (error,rows) {
if (error) {
res.json(error)
} else {
response.msg = 'Login Success';
}
});
}
});
router.post('/login', function(req,res) {
var password = req.body.password;
var user_name = req.body.user_name;
var response = {};
var hash = db.query('SELECT hash FROM user WHERE user_name = ?', [req.body.user_name]);
bcrypt.compare(password, hash, function(err, res) {
db.query('select user_id,email FROM user where password = ? AND user_name = ? OR email = ?',
[hash, req.body.user_name, req.body.user_name], function (error,rows) {
if (error) {
res.json(error)
} else {
response.msg = 'Login Success';
}
});
}
});