【问题标题】:Implement change password with Loopback使用 Loopback 实现更改密码
【发布时间】:2016-02-17 05:41:23
【问题描述】:

我正在尝试使用 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'});
        });
      }
    });
  });
});

【问题讨论】:

    标签: javascript node.js loopbackjs strongloop


    【解决方案1】:

    使用在源代码中看到的内置User.hashPassword

    //Hash the plain password
    user.updateAttribute('password', User.hashPassword(req.body.password), function(err, user) {
        ...
    });
    

    【讨论】:

    • 有了这个我得到TypeError: user.hashPassword is not a function我错过了什么?
    • 我使用了User.hashPassword(req.body.password),效果非常棒。非常感谢!
    • @VickyGonsalves 不客气,当您无法在环回中找出某些东西时,请务必检查源代码,这很有帮助
    • 伟大的建议 Medet!
    • 重要!小写的“user”为实际登录的用户实例,“User”为模型类型。
    【解决方案2】:

    这实际上是 loopback-datasource-juggler 2.45.0 中引入的一个错误。默认情况下应该对密码进行哈希处理。

    https://github.com/strongloop/loopback-datasource-juggler/issues/844

    https://github.com/strongloop/loopback/issues/2029

    所以请注意,如果您使用 user.hashpassword,它可能无法在未来的版本中使用,因为如果没有正确完成,它可能会散列一个已经散列的密码,但应该已经检查长度并检查$2$ 或任何哈希值的起始位。

    编辑:安装 loopback-datasource-juggler 2.45.1 应该会修复。

    【讨论】:

    • 谢谢.. 我不知道!
    【解决方案3】:

    这是我在 LoopBack / StrongLoop - IBM 项目中实现特定 updatePassword 远程方法的“完整”解决方案。 请验证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"
         }
       ...
       ],
       ...
    }
    

    注意:可以使用 MyUserModel 上的 PUT 请求并在正文中指定 { "password":"...newpassword..."} 来执行相同的功能。但是为了对新密码实施安全策略,使用特定的远程方法可能比这个技巧更方便。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-26
      • 1970-01-01
      • 2021-09-02
      • 1970-01-01
      • 2021-02-09
      • 2014-06-19
      • 2012-10-25
      • 2012-07-26
      相关资源
      最近更新 更多