简体   繁体   中英

Trying to hash a password using bcrypt inside an async function

Following on from this question .

I feel like I'm almost there, but my incomplete understanding of async is preventing me from solving this. I'm basically trying to just hash a password using bcrypt and have decided to seperate out the hashPassword function so that I can potentially use it in other parts of the app.

hashedPassword keeps returning undefined though...

userSchema.pre('save', async function (next) {

  let user = this
  const password = user.password;

  const hashedPassword = await hashPassword(user);
  user.password = hashedPassword

  next()

})

async function hashPassword (user) {

  const password = user.password
  const saltRounds = 10;

  const hashedPassword = await bcrypt.hash(password, saltRounds, function(err, hash) {

    if (err) {
      return err;
    }

    return hash

  });

  return hashedPassword

}

await dosent wait for bcrypt.hash because bcrypt.hash does not return a promise. Use the following method, which wraps bcrypt in a promise in order to use await .

async function hashPassword (user) {

  const password = user.password
  const saltRounds = 10;

  const hashedPassword = await new Promise((resolve, reject) => {
    bcrypt.hash(password, saltRounds, function(err, hash) {
      if (err) reject(err)
      resolve(hash)
    });
  })

  return hashedPassword
}

Update:-

The library has added code to return a promise which will make the use of async/await possible, which was not available earlier. the new way of usage would be as follows.

const hashedPassword = await bcrypt.hash(password, saltRounds)

By default, bcrypt.hash(password,10) will return as promise. please check here

Example: Run the code,

var bcrypt= require('bcrypt');

let password = "12345";


var hashPassword = async function(){
    console.log(bcrypt.hash(password,10));
    var hashPwd = await bcrypt.hash(password,10);
    console.log(hashPwd);
}

hashPassword();

Output:

Promise { <pending> }
$2b$10$8Y5Oj329TeEh8weYpJA6EOE39AA/BXVFOEUn1YOFC.sf1chUi4H8i

When you use await inside the async function, it will wait untill it get resolved from the promise.

使用方法 bcrypt.hashSync(),它是同步开箱即用的。

const hashedPassword = bcrypt.hashSync(password,saltRounds);

Hashing bcrypt asynchronously should be like this

bcrypt.hash(password, saltRounds, function(err, hash) {
  if (err) {
     throw err;
  }
  // Do whatever you like with the hash
});

If you are confused with sync and async. You need to read more about them. There are a lot of good articles out there.

You need to look here in the documentation.

Async methods that accept a callback, return a Promise when callback is not specified if Promise support is available.

So, if your function call takes in a callback then you can't use await on it since this function signature doesn't return a Promise . In order to use await you need to remove the callback function. You can also wrap it in a Promise and await on it but that's a bit overkill since the library already provides a mechanism to do so.

Code refactor:

try {
   // I removed the callbackFn argument
   const hashedPassword = await bcrypt.hash(password, saltRounds)
} catch (e) {
   console.log(e)
}
const hashedPassword = (password, salt) => {
    return new Promise((resolve, reject) => {
        bcrpyt.hash(password, salt, (err, hash) => {
            if (err) reject();
            resolve(hash);
        });
    });
};
hashedPassword('password', 10).then((passwordHash) => {
    console.log(passwordHash);
});

Had same issue... solved by assigning the Boolean value from a function:

compareHash = (password, hashedPassword) => {
if (!password || !hashedPassword) {
  return Promise.resolve(false);
}
return bcrypt.compare(password, hashedPassword);
 };

Here the 2 arguments will not be undefined, which is the cause of issue. And calling the function:

let hashCompare = this.compareHash(model.password, entity.password);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM