2016-02-17 15 views
7

ループバックの組み込みメソッドを使用してパスワード変更機能を実装しようとしていますが、正常に動作しますが、パスワードは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'}); 
     }); 
     } 
    }); 
    }); 
}); 

答えて

7

ソースコードで見られるビルトインUser.hashPassword使用

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

これは私が 'TypeError:user.hashPasswordは関数ではありません.'私は何が欠けていますか? –

+0

私は 'User.hashPassword(req.body.password)'を使用しましたが、それは魅力的な働きをしました..ありがとうございました! –

+1

@VickyGonsalvesループバックで何かを見つけられない場合は、いつでもソースコードをチェックしてください。それは大変役に立ちます –

4

これは実際には、ループバック・データソース-ジャグラー2.45.0で導入されたバグです。パスワードはデフォルトでハッシュされる必要があります。

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

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

だから、あなたは、これが固定されている場合、それは将来のバージョンでは動作しない場合がありuser.hashpassword使用している場合は正しく行われていない場合、それはPWすでにハッシュハッシュかもしれないので注意してください、しかし、すでに$ 2 $のチェックや、スタートビットがハッシュ値のものであるかどうかをチェックする長さのチェックが必要です。

を編集します。loopback-datasource-jugglerの2.45.1をインストールしてください。修正する必要があります。

+0

ありがとう。私はそれを知らなかった! –

1

LoopBack/StrongLoop-IBMプロジェクトで特定のupdatePasswordリモートメソッドを実装する "完全な"ソリューションがここにあります。 loopback-datasource-jugglerパッケージのバージョンが2.45.1(npm list loopback-datasource-juggler)以上かどうかを確認してください。 私のユーザモデルはMyUserModelと呼ばれ、内蔵されたモデルUserから継承されます。

"私のユーザー-model.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'} 
    } 
); 

... 
}; 

"私のユーザー-model.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: The same functionality can be performed using a PUT request on MyUserModel and just specifying { "password":"...newpassword..."} in the body. But it probably is more convenient to have a specific remote method than this trick in order to enforce security policy on the new password.

関連する問題