简体   繁体   中英

bcrypt compare returning false when password contains numbers

I'm using node-bcrypt along with PostgreSQL (via Sequelizejs to hash and save passwords.

The user's password is hashed in a beforeValidate hook like so:

beforeValidate: function(user, model, cb) {
        bcrypt.hash(user.password, 10, function(err, hash) {
          if ( err ) { throw err; }
          user.password = hash;
          cb(null, user);
        });
      }

The column on the User model in which the hash is stored is defined as:

password: { type: DataTypes.STRING, allowNull: false }

When a user is logging in (I'm using Passport for authentication), the function looks like this:

passport.use(new LocalStrategy(function(username, password, done) {
    models.User.find({ username: username }).then(function(retrievedUser) {
      if ( !_.isEmpty(retrievedUser) ) {
        retrievedUser.verifyPassword(password, function(err, result) {
          if ( err || !result ) {
            return done(null, false, { message: 'Incorrect password.' });
          } else {
            return done(null, retrievedUser);
          }
        });
      } else {
        return done(null, false, { message: 'User could not be found at that username.' });
      }
    }).catch(function(err) {
      return done(err);
    });
  }));

Which retrieves the user correctly.

And the comparison, defined here on the User model:

instanceMethods: {
      verifyPassword: function(password, cb) {
        bcrypt.compare(password, this.password, cb);
      }
    }

The verification passes just fine if the password only contains letters and/or symbols. However, any passwords with numbers never pass the comparison. Any ideas?

In your beforeValidate function you are passing in 10 as the salt you need to generate your salt, change that function to this

beforeValidate: function(user, model, cb) {
    var salt = bcrypt.genSalt(10);
    bcrypt.hash(user.password, salt, function(err, hash) {
      if ( err ) { throw err; }
      user.password = hash;
      cb(null, user);
    });
  }

Well, embarrassingly (and as some people suspected), this was completely unrelated to Bcrypt.

In my authentication function, I was attempting to fetch the appropriate user with the following:

models.User.find({ username: username })

However, the query should have been specified in a where field, like so:

models.User.find({
   where: { username: username }
})

This was causing the authentication method to always be comparing to the password for the first user in the database (returned by default when no where field is specified). Thus, it SEEMED to work because the first user's letters-only password always worked but no following passwords worked (in reality, even a letters-only password would have failed for other users).

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