使用 bcrypt 确保密码没有被重复
Using bcrypt to make sure password hasn't been repeated
我正在使用 bcrypt 对数据库中的密码进行哈希处理。我正在尝试添加一项功能以确保用户何时无法重复使用密码。我想做的是遍历以前的密码列表以检查是否可以重用。现在我可以做这样简单的事情:
var reused = false;
for (let i = 0; i < oldPWs.length; i++) {
reused = bcrypt.compareSync(newPassword, oldPWs[i].PASSWORD);
if (reused){
console.log("Password is a repeat");
break;
}
}
但是,根据文档,不建议使用同步功能执行此操作,因为这会阻止其他服务器请求。是否有推荐的方法来检查密码是否对哈希列表有效?我不认为它可以通过 bcrypt.compare()
函数的回调函数来完成,但也许有承诺......任何建议将不胜感激。
@Zhephard 将我推向了正确的方向,所以我将他的回答标记为正确。我使用的实际代码如下:
var promises = [];
for (let i = 0; i < oldPWs.length; i++) {
promises.push(bcrypt.compare(newPassword, oldPWs[i].PASSWORD))
}
Promise.all(promises).then((results)=>{
console.log("All done:", results)
if (results.includes(true)) {
// alert users password has been repeated
console.log("Password is repeat")
} else {
// allow password change
console.log("Password is new")
}
})
根据我在 API 上看到的内容,您似乎做对了,如果使用 promises 是您的选择之一,您可以做类似的事情
oldPWs.map((p) => bcrypt.compare(p.PASSWORD, hash)
.then((res) => {
if (res) console.log('Password repeated');
}));
这种方式很短,您也不必介意对旧的检索密码使用索引
我相信这就是你想要的。
为此,您可能会像这样创建一个异步函数
//Non blocking bcrypt
async function reuse_check(plaintext, oldPw) {
var promise = new Promise(function (res, rej){
bcrypt.compare(plaintext, oldPw, function(err, BCRYPT_RES){
if(err){
console.log(err)
}
else {
if (BCRYPT_RES) {
res(true)
}
else {
res(false)
}
}
})
})
let isReused = await promise
return isReused
}
//Loops, await is valid in async only
async function looper(plaintext, oldPwsArray) {
var reused = false
for (let i = 0; i < oldPwsArray.length; i++) {
var temp = await reuse_check(plaintext, oldPwsArray[i])
if (temp) {
reused = true
break
}
else {
}
}
if (reused) {
console.log("Reused")
}
}
//Driver
looper(plaintext, oldPwsArray)
这应该能达到您的目的。
您可以在下面尝试。
使用没有回调的 bcrypt.compare() returns 承诺。
如果找到相同的密码,您可以立即等待 bcrypt.comapre() 和 break()。
(async () => {
for(let i=0 ; oldPWs.length; i++){
try {
let isEqual = await bcrypt.compare(newPassword, oldPWs[i].PASSWORD);
if(isEqual){
console.log("Password is a repeat");
break;
}
} catch (err) {
console.error('something wrong');
console.log(err)
}
}
})();
我正在使用 bcrypt 对数据库中的密码进行哈希处理。我正在尝试添加一项功能以确保用户何时无法重复使用密码。我想做的是遍历以前的密码列表以检查是否可以重用。现在我可以做这样简单的事情:
var reused = false;
for (let i = 0; i < oldPWs.length; i++) {
reused = bcrypt.compareSync(newPassword, oldPWs[i].PASSWORD);
if (reused){
console.log("Password is a repeat");
break;
}
}
但是,根据文档,不建议使用同步功能执行此操作,因为这会阻止其他服务器请求。是否有推荐的方法来检查密码是否对哈希列表有效?我不认为它可以通过 bcrypt.compare()
函数的回调函数来完成,但也许有承诺......任何建议将不胜感激。
@Zhephard 将我推向了正确的方向,所以我将他的回答标记为正确。我使用的实际代码如下:
var promises = [];
for (let i = 0; i < oldPWs.length; i++) {
promises.push(bcrypt.compare(newPassword, oldPWs[i].PASSWORD))
}
Promise.all(promises).then((results)=>{
console.log("All done:", results)
if (results.includes(true)) {
// alert users password has been repeated
console.log("Password is repeat")
} else {
// allow password change
console.log("Password is new")
}
})
根据我在 API 上看到的内容,您似乎做对了,如果使用 promises 是您的选择之一,您可以做类似的事情
oldPWs.map((p) => bcrypt.compare(p.PASSWORD, hash)
.then((res) => {
if (res) console.log('Password repeated');
}));
这种方式很短,您也不必介意对旧的检索密码使用索引
我相信这就是你想要的。
为此,您可能会像这样创建一个异步函数
//Non blocking bcrypt
async function reuse_check(plaintext, oldPw) {
var promise = new Promise(function (res, rej){
bcrypt.compare(plaintext, oldPw, function(err, BCRYPT_RES){
if(err){
console.log(err)
}
else {
if (BCRYPT_RES) {
res(true)
}
else {
res(false)
}
}
})
})
let isReused = await promise
return isReused
}
//Loops, await is valid in async only
async function looper(plaintext, oldPwsArray) {
var reused = false
for (let i = 0; i < oldPwsArray.length; i++) {
var temp = await reuse_check(plaintext, oldPwsArray[i])
if (temp) {
reused = true
break
}
else {
}
}
if (reused) {
console.log("Reused")
}
}
//Driver
looper(plaintext, oldPwsArray)
这应该能达到您的目的。
您可以在下面尝试。
使用没有回调的 bcrypt.compare() returns 承诺。
如果找到相同的密码,您可以立即等待 bcrypt.comapre() 和 break()。
(async () => {
for(let i=0 ; oldPWs.length; i++){
try {
let isEqual = await bcrypt.compare(newPassword, oldPWs[i].PASSWORD);
if(isEqual){
console.log("Password is a repeat");
break;
}
} catch (err) {
console.error('something wrong');
console.log(err)
}
}
})();