使用 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)
        }
    }
})();