Как обновить соль и значение хэша в MongoDB, когда пользователь меняет пароль в nodejs?

#node.js #mongodb #handlebars.js #password-hash #change-password

#node.js #mongodb #handlebars.js #пароль-хэш #изменить пароль

Вопрос:

Я должен реализовать функциональность для пользователя, который может после входа в систему изменить пароль на новый. Для этого я хочу обновить значение hash и salt для нового набора паролей. Как я могу это сделать? Поскольку при регистрации я впервые сохраняю пароль в форме хэша и соли в MongoDB. Как я могу обновить это сейчас?

Вот код, который я пытаюсь использовать для смены пароля:

     router.get('/api/changePassword', function(req,res,next){
      req.checkBody('oldPass', 'Empty Password').notEmpty();
      req.checkBody('newPass', 'Password do not match').equals(req.body.confirmPassword).notEmpty();
    
      var user = new User();
      user.setPassword(req.body.newPass);
  user.save(function (err,data) {
        if (err) {
          res.render('register', {errorMessages: err});
        } else {
console.log("password set successfully");

    }
})
})
  

Но здесь я сомневаюсь, что он будет обновлен в базе данных существующего пользователя, поскольку я снова создаю объект user здесь и сохраняю его. Будет ли он снова создавать нового пользователя в коллекциях и обновлять значение хэша и соли для этого? Как затем обновить существующий хэш пароля пользователя и значение соли?

Ниже приведен код схемы пользователя модели хэша и соли:

 userSchema.methods.setPassword = function(password) {
  this.salt = crypto.randomBytes(16).toString('hex');
  this.hash = crypto.pbkdf2Sync(password, this.salt, 1000, 64, 'sha1').toString('hex');
};

userSchema.methods.validPassword = function(password) {
  var hash = crypto.pbkdf2Sync(password, this.salt, 1000, 64, 'sha1').toString('hex');
  return this.hash === hash;
};

module.exports = mongoose.model('User', userSchema); 
  

И это код маршрута страницы регистрации, в первый раз, когда пользователь регистрируется и вводит пароль:

 router.route('/register')
  .get(function(req, res, next) {
    res.render('register', { title: 'Register a new account'});
  })
  .post(function(req, res, next) {
    req.checkBody('name', 'Empty Name').notEmpty();
    req.checkBody('email', 'Invalid Email').isEmail();
    req.checkBody('location', 'Empty Location').notEmpty();
    req.checkBody('password', 'Empty Password').notEmpty();
    req.checkBody('password', 'Password do not match').equals(req.body.confirmPassword).notEmpty();

    var errors = req.validationErrors();
    if (errors) {
      res.render('register', {
        name: req.body.name,
        email: req.body.email,
        location:req.body.location,
        errorMessages: errors
      });
    } else {
      var user = new User();
      user.name = req.body.name;
      user.email = req.body.email;
      user.location = req.body.location;
      user.setPassword(req.body.password);

      user.save(function (err,data) {
        if (err) {
          res.render('register', {errorMessages: err});
        } else {
console.log("user saved successfully");

}
})
  

Комментарии:

1. Мне интересно, в чем проблема, остаются ли атрибуты соли и хэша неизменными после запуска setPassword() метода? Кроме того, при смене пароля вы можете просто выполнить a .find() для пользователя вместо создания нового.

2. ОК. Но после нахождения пользователя, как затем обновить пароль? Должен ли я использовать .save(). Если да, то как? Поскольку он хранит значение has и salt в базе данных, а не фактический пароль. Так что, возможно, мне все равно придется запустить команду SetPassword! @gegs921

3. Мое второе сомнение: нужно ли сохранять пароль после SetPassword? Или только с помощью этой команды он обновляет соль и значение хэша? @gegs921

4. Я думаю, что вам нужно переименовать setPassword в createPassword , затем добавить другой метод, который принимает проверку пароля и createdPassword в качестве параметров (вызывается этот новый метод setPassword ). Затем внутри этого нового метода вы будете использовать .find() метод для поиска текущего пользователя на основе идентификатора или имени пользователя, а затем использовать .update() метод для обновления данных этого пользователя до нового пароля, если все предыдущие проверки пройдены. Вы можете найти объяснения методов .find() и .update() в документации mongoose.

5. Таким образом, вы просто обновляете данные и не создаете нового пользователя.

Ответ №1:

Извините, мое предыдущее объяснение было неверным, поэтому я напишу это как ответ. На самом деле вы не сможете получить доступ к объекту User только в методе, поэтому вам нужно будет сделать что-то вроде следующего:

создайте функцию, User.find() которая возвращает пользователя.

Затем передайте этого пользователя в качестве параметра новому методу, который вы создали, как я описал в комментарии выше, и перейдите к .update() этому пользователю, который был передан в setPassword() метод в качестве параметра.

Итак, ваши методы для схемы должны быть:

createPassword()

validPassword()

setPassword()

и та часть вашего кода, где у вас на самом деле есть функция, которая использует эти методы для установки этих данных, должна выглядеть примерно так:

 function findUser() {
  return User;
}

function setPassword(password) {
  User.setPassword(User, password, passwordValid /*This is a boolean*/)
}
  

Комментарии:

1. ничего не понимаю @gegs921.