如何在Sequelize .then中执行bcrypt.compare?

问题描述 投票:0回答:3

我正在尝试构建一个登录页面,在其中使用 Sequelize 从 mysql 数据库获取哈希密码,然后调用 bcrypt Compare 对密码进行哈希处理,并将其与用户的登录输入进行比较以进行身份验证。

但是,bcrypt Compare 的执行速度始终比 return 慢,导致该值始终为“”。我知道这与异步行为有关,但我不知道如何正确编写此代码以使其工作。

     authenticate: (req, res) => {

    let userDetails = req.query;

    User.findOne({
      where: {
        username: userDetails.username
      }
    })
    .then((user) => {
      // How can I make this so, correctPassword() finishes
      // and then the authenticated variable will be either false or true?

      let authenticated = correctPassword(userDetails.password, user.password);
      return authenticated;
    })
    .then((authenticated) => {
      // right now authenticated is "" in client side console.

      res.send(authenticated);
    })
    .catch((error) => {
      console.log('there was an error: ', error);
    });
  }
}

const correctPassword = (enteredPassword, originalPassword) => {
  return bcrypt.compare(enteredPassword, originalPassword, (err, res) =>{
    return res;
  });
}
javascript node.js asynchronous sequelize.js bcrypt
3个回答
1
投票

你就快到了。您正确地直觉到

correctPassword
是异步执行的,尽管它写得好像是同步的。

首先,让我们做出

correctPassword
的承诺,这样我们就可以使用
async/await
或调用
.then
来实现它

const correctPassword = (enteredPassword, originalPassword) => {
  return new Promise(resolve => {
    bcrypt.compare(enteredPassword, originalPassword, (err, res) =>{
      resolve(res)
    });  
  })
}

接下来,您有两种方法可以确保代码中的操作顺序正确执行:

(推荐)使用

async/await
语法允许我们编写看起来同步的代码:

authenticate: async (req, res) => {
  let userDetails = req.query;
  try {
    const user = await User.findOne({
      where: {
        username: userDetails.username
      }
    });

    const authenticated = await correctPassword(userDetails.password, user.password);

    res.send(authenticated);        
  } catch(e) {
    res.status(400).send(e)
  }
}

继续使用承诺:

authenticate: (req, res) => {
  let userDetails = req.query;
  User.findOne({
    where: {
      username: userDetails.username
    }
  }).then(() => {
    correctPassword(userDetails.password, user.password)
      .then(authenticated => {
        res.send(authenticated)
      })
      .catch(e => {
        res.send(e)
      })
  })
}

0
投票

您不能将异步函数分配给稍后由同步代码使用的变量。如果你想做同步功能,你可以使用

await/aync
。但在这里我建议您也使用 Promise 进行比较函数。

User.findOne({
  where: {
    username: userDetails.username
  }
})
.then((user) => {
  return correctPassword(userDetails.password, user.password);
})
.then((authenticated) => {
  res.send(authenticated);
})

Bcrypt 还支持 Promise。

const correctPassword = (enteredPassword, originalPassword) => {
  return bcrypt.compare(enteredPassword, originalPassword).then((res) =>{
    return res;
  });
}

0
投票
let hashpassword = 'yourhashpassword'

const verified = bcrypt.compareSync(password, dbPasswordHash);

if (!verified)
  throw new Error('error')
© www.soinside.com 2019 - 2024. All rights reserved.