Реализовать изменение пароля с помощью Loopback
Я пытаюсь реализовать функцию изменения пароля с помощью встроенного метода Loopback, он работает нормально, но он не обновляет пароль с hash
вместо этого он просто сохраняет простой текст в БД. Я использую loopback-component-passport
пакет npm в этом проекте. Я обыскал много сайтов, но я не могу найти правильный способ реализации этой функции. Кто-нибудь знает, как это сделать?
//Change user's pasword
app.post('/change-password', function(req, res, next) {
var User = app.models.user;
if (!req.accessToken) return res.sendStatus(401);
//verify passwords match
if (!req.body.password || !req.body.confirmation ||
req.body.password !== req.body.confirmation) {
return res.sendStatus(400, new Error('Passwords do not match'));
}
User.findById(req.accessToken.userId, function(err, user) {
if (err) return res.sendStatus(404);
user.hasPassword(req.body.oldPassword, function(err, isMatch) {
if (!isMatch) {
return res.sendStatus(401);
} else {
user.updateAttribute('password', req.body.password, function(err, user) {
if (err) return res.sendStatus(404);
console.log('> password change request processed successfully');
res.status(200).json({msg: 'password change request processed successfully'});
});
}
});
});
});
3 ответов
использовать встроенный User.hashPassword
который видел в исходном коде
//Hash the plain password
user.updateAttribute('password', User.hashPassword(req.body.password), function(err, user) {
...
});
Это на самом деле ошибка, которая была введена с loopback-datasource-juggler 2.45.0. Пароль должен быть хэширован по умолчанию.
https://github.com/strongloop/loopback-datasource-juggler/issues/844
https://github.com/strongloop/loopback/issues/2029
Так что будьте осторожны, если вы используете пользователей.hashpassword он может не работать в будущей версии, когда это исправлено, так как он может хэшировать уже хэшированный pw, если не сделано правильно, но уже должна быть проверка длины плюс проверка на $2$ или любой начальный бит для хэш-значений.
редактировать: установите 2.45.1 loopback-datasource-juggler, и он должен быть исправлен.
вот мое "полное" решение для реализации конкретного удаленного метода updatePassword в проекте LoopBack / StrongLoop - IBM.
Пожалуйста, убедитесь, что loopback-datasource-juggler
пакет имеет более высокую или равную версии, чем 2.45.1 (npm list loopback-datasource-juggler
).
Моя модель пользователя называется MyUserModel
и наследуется от встроенной модели User
:
"мой-пользователей-модель.js"
module.exports = function (MyUserModel) {
...
MyUserModel.updatePassword = function (ctx, emailVerify, oldPassword, newPassword, cb) {
var newErrMsg, newErr;
try {
this.findOne({where: {id: ctx.req.accessToken.userId, email: emailVerify}}, function (err, user) {
if (err) {
cb(err);
} else if (!user) {
newErrMsg = "No match between provided current logged user and email";
newErr = new Error(newErrMsg);
newErr.statusCode = 401;
newErr.code = 'LOGIN_FAILED_EMAIL';
cb(newErr);
} else {
user.hasPassword(oldPassword, function (err, isMatch) {
if (isMatch) {
// TODO ...further verifications should be done here (e.g. non-empty new password, complex enough password etc.)...
user.updateAttributes({'password': newPassword}, function (err, instance) {
if (err) {
cb(err);
} else {
cb(null, true);
}
});
} else {
newErrMsg = 'User specified wrong current password !';
newErr = new Error(newErrMsg);
newErr.statusCode = 401;
newErr.code = 'LOGIN_FAILED_PWD';
return cb(newErr);
}
});
}
});
} catch (err) {
logger.error(err);
cb(err);
}
};
MyUserModel.remoteMethod(
'updatePassword',
{
description: "Allows a logged user to change his/her password.",
http: {verb: 'put'},
accepts: [
{arg: 'ctx', type: 'object', http: {source: 'context'}},
{arg: 'emailVerify', type: 'string', required: true, description: "The user email, just for verification"},
{arg: 'oldPassword', type: 'string', required: true, description: "The user old password"},
{arg: 'newPassword', type: 'string', required: true, description: "The user NEW password"}
],
returns: {arg: 'passwordChange', type: 'boolean'}
}
);
...
};
"мой-пользователей-модель.в JSON"
{
"name": "MyUserModel",
"base": "User",
...
"acls": [
...
{
"comment":"allow authenticated users to change their password",
"accessType": "EXECUTE",
"property":"updatePassword",
"principalType": "ROLE",
"principalId": "$authenticated",
"permission": "ALLOW"
}
...
],
...
}
NB: та же функциональность может быть выполнена с помощью запроса PUT on MyUserModel и просто указав { "пароль":"...newpassword..."} в теле. Но, вероятно, удобнее иметь конкретный удаленный метод, чем этот трюк, чтобы обеспечить политику безопасности нового пароля.