Last active
May 18, 2021 09:58
-
-
Save dmh2000/1609820c17c5daf95298f54324360950 to your computer and use it in GitHub Desktop.
Using bcrypt with promises to hash a password and then verify it
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const bcrypt = require("bcrypt"); | |
// use this library in case your version of node doesn't support Promise | |
// const Promise = require("promise"); | |
let password = "hello"; | |
let stored_hash = ""; | |
// first generate a random salt | |
function genSalt(password) { | |
return new Promise((resolve, reject) => { | |
bcrypt.genSalt(10, function(err, salt) { | |
if (err) { | |
reject(err); | |
} else { | |
resolve({ | |
salt: salt, | |
password: password | |
}); | |
} | |
}); | |
}); | |
} | |
// hash the password with the salt | |
function genHash(salt, password) { | |
return new Promise((resolve, reject) => { | |
bcrypt.hash(password, salt, function(err, hash) { | |
if (err) { | |
reject(err); | |
} else { | |
resolve({ | |
salt: salt, | |
password: password, | |
hash: hash | |
}); | |
} | |
}); | |
}); | |
} | |
// execute in sequence | |
console.log("store"); | |
genSalt(password) | |
.then(function(result) { | |
return genHash(result.salt, result.password); | |
}) | |
.then(function(result) { | |
console.log("store hash in user profile :", result); | |
stored_hash = result.hash; | |
}) | |
.catch(function(err) { | |
console.log(err); | |
}); | |
// ===================================================== | |
function lookupUser(user, passwd) { | |
return new Promise((resolve, reject) => { | |
// lookup the user in the stored database | |
// in this case its not async so just resolve with the stored hash | |
resolve({ | |
user: user, | |
password: passwd, | |
hash1: stored_hash | |
}); | |
}); | |
} | |
function reHash(user, password, hash1) { | |
// extract salt from existing has (30 characters) | |
let salt = hash1.substr(0, 30); | |
return new Promise((resolve, reject) => { | |
bcrypt.hash(password, salt, function(err, hash2) { | |
if (err) { | |
reject({ | |
err, | |
user: user, | |
salt: salt, | |
password: password, | |
hash1: hash1, // stored hash | |
hash2: hash2 // generated hash | |
}); | |
} else { | |
resolve({ | |
user: user, | |
salt: salt, | |
password: password, | |
hash1: hash1, // stored hash | |
hash2: hash2 // generated hash | |
}); | |
} | |
}); | |
}); | |
} | |
// lookup and verify | |
setTimeout(function() { | |
console.log("verify"); | |
lookupUser("joe", password) | |
.then(function(result) { | |
return reHash(result.user, result.password, result.hash1); | |
}) | |
.then(function(result) { | |
console.log(result.hash1); | |
console.log(result.hash2); | |
if (result.hash1 === result.hash2) { | |
console.log("verified"); | |
} else { | |
console.log("failed"); | |
} | |
}) | |
.catch(function(err) { | |
console.log(err); | |
}); | |
}, 1000); |
I love this man.
Thanks for this ... Helped a ton
glad i could help. I worked this up after I failed horribly on an interview question about bcrypt.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is ungodly awesome, thank you!
Turns out, if you want to use bcrypt and sequelize simultaneously, you rely on such solution much more intensely, given that the latter uses a lot of Promises.