#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.