3

I have a custom method defined in my mongoosejs ODM schema which allows me to generate a salt and encode the given password.

Because node.js crypto modules are async I have to put the password encoding into the salt callback (otherwise there is no salt at all, because generation takes time). But this isn't the main problem. The main problem is that I need to set the salt and password properties of mongoosejs object. Usually you do this with "this" but "this" doesn't work in a callback (it refers to the callback instead of the parent object).

So, how could I get back my encoded password and the salt from an async call?

methods: {
    setPassword: function(password) {
        crypto.randomBytes(32, function(err, buf) {
            var salt = buf.toString('hex');
            this.salt = salt;
            crypto.pbkdf2(password, salt, 25000, 512, function(err, encodedPassword) {
                if (err) throw err;
                this.password = encodedPassword;
            });
        });
    }
}

I also tried using return statements but they don't return anything...

1 Answer 1

7

You can either set a variable to this outside the callback and use it inside:

methods: {
    setPassword: function(password) {
        crypto.randomBytes(32, function(err, buf) {
            var self = this;
            var salt = buf.toString('hex');
            this.salt = salt;
            crypto.pbkdf2(password, salt, 25000, 512, function(err, encodedPassword) {
                if (err) throw err;
                self.password = encodedPassword;
            });
        });
    }
}

Or you can bind the callback function so that the value of this is retained:

methods: {
    setPassword: function(password) {
        crypto.randomBytes(32, function(err, buf) {
            var salt = buf.toString('hex');
            this.salt = salt;
            crypto.pbkdf2(password, salt, 25000, 512, function(err, encodedPassword) {
                if (err) throw err;
                this.password = encodedPassword;
            }.bind(this));
        });
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Hi, what is the keywoard of this approach (scope binding?).
bind, which is a method on Function's prototype. crypto.pbkdf2(password, salt, 25000, 512, function() { ... }.bind(this)). See bind on MDN.

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.