0

I'm unable to store bcrypt hashed password from JSON into mongodb using mongoose. I think there is a mistake in my implementation of setPassword schema method. I've replaced 'bcrypt' with 'crypto' implementation and it worked fine. The hashed string was stored in database. But unable to do so with 'bcrypt'

My model.js implementation

const mongoose = require('mongoose');
const bcrypt = require('bcrypt');

const Schema = mongoose.Schema;

// User Schema
const userSchema = new Schema({
  username: {
    type: String,
    index: true
  },
  password: {
    type: String
  },
  email: {
    type: String
  },
  name: {
    type: String
  }
});

userSchema.methods.setPassword =  function(password) {
  const saltRounds = 10;
  bcrypt.hash(password, saltRounds, function(err, hash) {
    this.password = hash;
  });
};

mongoose.model('User', userSchema);

My router controller implementation

const passport = require('passport');
const mongoose = require('mongoose');
const User = mongoose.model('User');

const register = (req, res) => {

  const newUser = new User();

  newUser.name = req.body.name;
  newUser.email = req.body.email;
  newUser.username = req.body.username;
  newUser.setPassword(req.body.password);

  newUser.save((err) => {
    // Validations error
    if (err) {
      res.status(400).json(err);
      return;
    }

    res.status(200).json({
      success: true,
      message: 'Registration Successful'
    });

  });
};
4
  • 1
    There could be an error generated by bcrypt.hash that you're not verifying. Commented Sep 10, 2017 at 11:55
  • @BrahmaDev I've added the line if (err) throw err; but it still doesn't throw any error. Commented Sep 10, 2017 at 18:51
  • Can you try the synchronous version. this.password=bcrypt.hashSync(password, saltRounds); Commented Sep 10, 2017 at 20:36
  • Thank you. bcrypt.hashSync(password, saltRoutnds); worked. Seems this.password is not pointing to newUser inside bcrypt.hash(). Any idea how to solve this? Commented Sep 10, 2017 at 20:44

1 Answer 1

1

this points to bcrypt.hash not the userSchema object.

userSchema.methods.setPassword =  function(password) {
  const saltRounds = 10;
  var that = this;
  bcrypt.hash(password, saltRounds, function(err, hash) {
    that.password = hash;
  });
};

UPDATE: Use callback or promises

userSchema.methods.setPassword =  function(password, cb) {
  const saltRounds = 10;
  var that = this;
  bcrypt.hash(password, saltRounds, function(err, hash) {
    that.password = hash;
    cb();
  });
};

newUser.setPassword(req.body.password, function(){
    //Rest of code
});
Sign up to request clarification or add additional context in comments.

2 Comments

This is not working. Printing 'that.password' inside bcrypt is giving hash but printing undefined outside the bcrypt.
@JajatiKeshariR If that.password remains undefined then that would mean bcrypt.hash is truly asynchronous and you'd need to wait for callback.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.