I don't know why this hash password code does not work.
I did install bcrypt, also, it should go to the line (res.send("testing"))if the passwords are the same but anyway in all situations password does not match is coming even they are the same.
Here is my code:
const mysql = require('mysql');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
const db = mysql.createConnection({
host: process.env.DATABASE_host,
user: process.env.DATABASE_user,
password: process.env.DATABASE_password,
database: process.env.DATABASE,
});
exports.form = (req, res) => {
console.log(req.body);
const { name, email, password, confirmPassword } = req.body;
db.query(
'SELECT email FROM users WHERE email=?',
[email],
async (error, results) => {
if (error) {
console.log(error);
}
if (results.length > 0) {
return res.render('form', {
message: 'that email is already in use',
});
} else if (password !== confirmPassword) {
return res.render('form', {
message: 'passwords not match',
});
}
let hashedPassword = await bcrypt.hash('password', 8);
console.log(hashedPassword);
res.send('testing');
}
);
};
``
[enter image description here][1]
[1]: https://i.stack.imgur.com/ToNvN.png
and always (passwords not match) comes even as u see in pic the passwords are same
Every time you call bcrypt.hash() you will get a different hash string, even with the same password, this is because the hashes are salted.
To check whether the hashes are equal, you need to test with bcrypt.compare(), you cannot compare to hashes directly. Some libraries also call it bcrypt.verify().
Edit: Assuming you use the node.bcrypt.js library:
const bcrypt = require('bcrypt');
// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
let hashToStoreInDb = bcrypt.hashSync('mypassword', 10);
// Check if the entered login password matches the stored hash.
// The salt and the cost factor will be extracted from existingHashFromDb.
let existingHashFromDb = hashToStoreInDb;
const isPasswordCorrect = bcrypt.compareSync('mypassword', existingHashFromDb);
Related
I'm working on my password reset flow and everything works except the actual bcrypt password reset. Following the "Technique 2 (auto-gen a salt and hash)" from about halfway down in the bcrypt docs suggests following below syntax:
Bcrypt docs syntax
const hash = bcrypt.hashSync(myPlaintextPassword, saltRounds);
// Store hash in your password DB.
My function
module.exports.submitNewPassword = async (req, res) => {
// console.log(req.body.password, req.params, req.headers.referer );
const slidedHeaderToken = req.headers.referer.slice(-40);
const user = await User.findOne({ resetPasswordToken: slidedHeaderToken, resetPasswordExpires: { $gt: Date.now() } });
console.log("submitNewPassword user ", user);
if (!user) {
console.log("user not found");
req.flash('error', "Password reset token is invalid or has expired");
res.render('users/reset')
} else {
// hash the new password
const hashedPassword = await bcrypt.hash(req.body.password, 12);
// update the user's password
user.password = hashedPassword;
user.resetPasswordToken = undefined;
user.resetPasswordExpires = undefined;
await user.save();
res.redirect('/users/login');
}
}
The resetPasswordToken and resetPasswordExpires are set properly in my previous function which emails out the password reset link and saves the two variables to the database.
The if statement logic and user.resetPasswordToken = undefined; and user.resetPasswordExpires = undefined; are executed properly but I can't get user.password = hashedPassword; to work.
How do I reset the user's password?
That's my code for backend of my app, creating account working very well but i dont know how to implement login system. Can someone help me? app.post(/login) <- here it starts
I have idea how it'll be works but i don't know how to do it. My idea is, get username and password from inputs, check if that exist in database, if it is go to dashboard, if not show error.
const express = require('express');
const app = express();
const mysql = require('mysql');
const cors = require('cors')
app.use(cors())
app.use(express.json())
const db = mysql.createConnection({
user: 'root',
host: 'localhost',
password: 'my_password',
database: 'myplan_database'
});
app.post('/create', (req, res) => {
const username = req.body.username
const mail = req.body.mail
const password = req.body.password
db.query(
'INSERT INTO users (username, mail, password) VALUES (?, ?, ?)',
[username, mail, password], (err, result) => {
if (err) {
console.log(err)
} else {
res.send('Values Insterted')
}
}
);
});
app.post('/login', (req, res) => {
const username = res.db.username
const password = res.db.password
db.query(
);
});
app.listen(3001, () => {
console.log('Server is running')
})
You can check the below code. Hope this code snippet will help you.
app.post("/login", (req, res) => {
// Capture the input fields
const username = req.body.username;
const password = req.body.password;
// Ensure the input fields exists and are not empty
if (username && password) {
// Execute SQL query that'll select the account from the database based on the specified username and password
db.query(
"SELECT * FROM users WHERE username = ? AND password = ?",
[username, password],
function (error, results, fields) {
// If there is an issue with the query, output the error
if (error) throw error;
// If the account exists
if (results.length > 0) {
// Authenticate the user
req.session.loggedin = true;
req.session.username = username;
// Redirect to home page
res.redirect("/dashboard");
} else {
res.send("Incorrect Username and/or Password!");
}
res.end();
}
);
} else {
res.send("Please enter Username and Password!");
res.end();
}
});
I'm trying to retrieve username from mysql database, the below code can successfully retrieve the username. However, when err occurs, code doesn't redirect to /signin. The page redirect to /admin instead. Though, if I add
res.redirect('/signin')
just before the last curly bracket, it will redirect to the signin page, but it won't able to retrieve the username.
I want it to redirect to signin page, how?
const connection = require('./connection')
const signin = (req, res) => {
var email = req.body.email
var password = req.body.password
let queryStr = `select username from users where email='${email}' and password='${password}'`
return connection.query(queryStr, (err, rows, fields) => {
if (err) {
res.redirect('/signin')
} else {
req.session.email = email
res.json(rows[0])
}
})
}
module.exports = signin
I think it has to do with async because the code execute the last line then go back to the else statement. I think that's why it goes to /admin page instead. but not fixed yet.
connection.js
const mysql=require('mysql')
var connection=mysql.createConnection({
host:'localhost',
user:'root',
password:'root',
database:'essencejoin',
})
connection.connect()
connection.query('SELECT 1 + 1 AS solution', function (err, rows, fields) {
if (err) throw err
console.log('The solution is: ', rows[0].solution)
})
module.exports=connection
Actually, You're Query is correct, But query doesn't return any rows. So if user not found on username table. It needs to signin page(This is your question correct?), For that you have to update the code like following,
const connection = require('./connection')
const signin = (req, res) => {
var email = req.body.email;
var password = req.body.password;
let queryStr = `select username from users where email='${email}' and password='${password}'`;
return connection.query(queryStr, (err, rows, fields) => {
if (err) {
res.redirect('/signin');
} else if(!rows.length) {
res.redirect('/signin');
}else {
req.session.email = email;
res.json(rows[0]);
}
})
}
module.exports = signin
It looks your code is being executed after you have returned it. You can use promisified version of the same code.
use mysql-promise. this is promisified wrapper around the same library you are using. then Your code will look something like this:
// install mysql-promise
npm i mysql-promise
connection.js
const mysql = require("mysql-promise");
async function getDBConn() {
const connection = mysql.createConnection({
host: "localhost",
user: "root",
password: "root",
database: "essencejoin"
});
await connection.connect();
return connection;
}
module.exports = getDBConn;
then use it like this:
//signin.js
const signin = (req, res) => {
const email = req.body.email;
const password = req.body.password;
const connection = getDBConn();
let queryStr = `select username from users where email='${email}' and password='${password}'`;
try {
await connection.query(queryStr);
req.session.email = email;
res.json(rows[0]);
} catch (error) {
console.log(error);
res.redirect("/signin");
}
};
module.exports = signin;
disclaimer: I have not tested this, even if this does not work this should give you a fair idea how to make it work
Without knowing too much about your project, I think you want to look into adding a status code with the express redirect.
index(req, res, next) {
topicQueries.getAllTopics((err, topics) => {
if (err) {
res.redirect(500, "static/index");
} else {
res.render("topics/index", { topics });
}
});
}
Something like that. Also, look out for other simple mistakes in your project, that may cause this, that deal with Express.
https://expressjs.com/en/api.html#res.redirect
I am very new to coding and am writing a personal project using node.js, express, mongoDB, and mongoose. I wrote most of it myself, however I hired someone to help me with the more advanced parts. I have lost contact with him and went back under the hood to create an admin panel I could use to write blog posts and other things. I am trying to write a middleware that only allows myself access to the route. However it is not working.
function adminAuth(req, res, next){
if(req.user.isAdmin){
return next();
} else {
res.redirect("/");
}
}
I am a bit confused of the syntax he has used to create a user schema and I am not sure how to add this isAdmin key value pair. Any help updating my users with an isAdmin key value would be extremely appreciated, and also helping me finish the middleware as (req.user.isAdmin) is not working! (If I do not provide the necessary code, please excuse my inexperience and tell me what you would like to see).
Here is the Auth route the coder I hired wrote that I am having trouble deciphering how to pass in new data to the user model.
const isAdmin = false;
const passwordHash = await bcrypt.hash(req.body.password, saltRounds);
const db = client.db(dbName);
const col = db.collection('users');
const user = {
email, firstName, lastName, password: passwordHash, isAdmin,
};
local strategy
module.exports = function localStrategy() {
passport.use(new Strategy(
{
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true
}, (req, email, password, done) => {
const url = process.env.MONGOLAB_URI;
const dbName = 'giftgrab';
(async function addUser() {
let client;
try {
client = await MongoClient.connect(url);
const db = client.db(dbName);
const col = db.collection('users');
const user = await col.findOne({ email });
debug('Found user by email');
debug(user);
if (!user) {
req.flash('error', 'The username or password is wrong');
done(null, false);
} else {
const match = await bcrypt.compare(password, user.password);
if (match) {
done(null, user);
} else {
req.flash('error', 'The username or password is wrong');
// we pass null because it did not error, just failed
done(null, false);
}
}
} catch (e) {
debug(e.stack);
}
client.close();
}());
}
Here is the Auth route the coder I hired wrote that I am having trouble deciphering how to pass in new data to the user model.
// add logic to check if the user is admin
const isAdmin = false;
// user data collected here. If you want to add an "isAdmin" property, this is the right place
const user = {
email, firstName, lastName, password: passwordHash, isAdmin,
};
// checking if the user already exists
const check = await col.findOne({ email });
if (check) {
req.flash('error', 'The user with this email already exists');
res.redirect('back');
} else {
// the user does not exist, insert a new one and authenticate
const results = await col.insertOne(user);
req.login(results.ops[0], () => {
res.redirect('/');
});
}
This is what related to adding the isAdmin property. In order to use req.user and req.isAuthenticated() you are going to need Passport.js. The user data stored in you session (req.user) is defined by your passport strategy so if you want to use the isAdmin property this way, you are going to need to set it there.
I am getting a bcrypt error stating that data and hash arguments are required, referencing line #44 in my routes.js file. From what I can tell, I am passing that information: the first parameter to bcrypt.compare is the user entered password, and the second is the hashed password retrieved from the db. What am I doing wrong?
bcrypt.compare(req.params.password, user.password, function...
routes.js
'use strict'
var express = require('express');
var router = express.Router();
var User = require('../app/models/user');
//password hashing
var bcrypt = require('bcrypt');
var count = 0;
router.use(function(req, res, next) {
count++;
console.log('API hit count = %s', count);
next();
});
// /users post(create new user) get(specific user)
router.route('/users')
.post(function(req,res) {
var user = new User();
user.username = req.body.username;
user.password = bcrypt.hashSync(req.body.password, 10);
//save the user and checkfor errors
user.save(function(err) {
if (err) {
res.send(err);
} else {
res.json({message: "User created!"});
}
});
})
router.route('/users/:username')
.get(function(req, res) {
var query = {
username: req.params.username,
};
User.findOne(query, function(err, user) {
if (err) {
res.send(err);
} else {
bcrypt.compare(req.params.password, user.password, function(err, res) {
if(err) {
console.log('Comparison error: ', err);
}
})
res.json(user);
}
});
})
bcrypt.compare takes 3 parameters; passwordToCheck, passwordHash, and a callback, respectively. (Check the documentation for examples)
This error means one or both of the first 2 parameters are either null or undefined. Therefore, make sure both of them are passed correctly. (Not as null or undefined)
Why do we face this error?
bcrypt Error: data and hash arguments required
Example:
bcrypt.compare(first, second)
Ans:
because either second key hash password does not exist (null or undefined) or first, which are compared to each other.
I used
const user = await User.find({email: req.body.email}) //which returned all users
//and unless i reference the first user in index 0, i can't pass user.password to the //bcrypt compare method because it's not a string
I changed it to
await User.findOne({email: req.body.email})//from which i can use user.password in the //bcrypt compare method
const passwordMatch = await bcrypt.compare(password, user.password);
Make sure you are giving raw password and hash password. This will return a boolean value.
I was having the same error when I was working with node js and mongoose. It was caused by attribute added to password called select: false in user model.
After remove it, it works.
I had the same error and the problem was a missing await when calling the function that reads from database
the steps for this problem :
1-ensure that the bcrypt function is have awir before it
2- if the problem is still exist ,then the problem is in the database (mongodb),try to create new database
an example:
const match = await bcrypt.compare(password,userValid.password);
if (match) {
res.send("login successful")
}else{
res.send("wrong password")
}
}
I was having the same issue, but I was using the synchronous form of bycrypt.compare(), which is bcrypt.compareSync(), so I changed it to bcrypt.compare() and it works perfectly.
Use
findOne({})
instead of
find()
Try console.log() to view and verify the data.
try {
let match = await bcrypt.compare(password, user.password)
if(!match){
return res.json({mass: "invalid Created"})
}else{
res.send('Wrong password')
}
console.log('success fulli', user)
res.render('pages/auth/login', {title: 'Login In Your Account'})
} catch(e) {
console.log(e)
next(e)
}
The problem also can appear when you forget to add await when loading data from the database.
I got the same error after forgetting to add "await".
let user = User.findOne({ username: req.body.username });
let user = await User.findOne({ username: req.body.username });
I also have this problem i set for password select:false in user model and solved by adding select('+password') to login route
i know all the questions are solved but maybe someone finds this code works for him
const passwordMatch = await bcrypt.compare(password, user.rows[0].s_password);
The name after the dot it's the name you use in your database, it's the field