2016-02-17 12 views
7

Ich versuche, das Change-Passwort-Funktion mit Loopbacks eingebauter Methode zu implementieren, Es funktioniert gut, aber es aktualisiert das Passwort nicht mit hash, stattdessen speichert es nur einen einfachen Text in der db. Ich verwende loopback-component-passport npm Paket in diesem Projekt. Ich habe viele Websites durchsucht, bin jedoch nicht in der Lage, den richtigen Weg zur Implementierung dieser Funktion zu finden. Hat jemand eine Idee, wie man das macht?Implementiere Passwort ändern mit Loopback

//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'}); 
     }); 
     } 
    }); 
    }); 
}); 

Antwort

7

Verwendung Einbau-User.hashPassword die

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

mit diesem bekomme ich 'TypeError: user.hashPassword ist keine Funktion' was fehlt mir? –

+0

Ich benutze 'User.hashPassword (req.body.password)' und es funktionierte wie ein Charme .. Vielen Dank! –

+1

@VickyGonsalves du bist willkommen, wenn Sie etwas in Loopback nicht herausfinden können, immer Quellcode, es hilft viel –

4

Dies ist tatsächlich ein Fehler im Quellcode gesehen, die mit Loopback-Datenquelle-Jongleur 2.45.0 eingeführt wurde. Das Passwort sollte standardmäßig gehashed sein.

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

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

Also Vorsicht, wenn Sie user.hashpassword es verwenden kann, in einer zukünftigen Version nicht funktionieren, wenn diese festgelegt ist, da es ein bereits gehasht Hash könnte pw wenn nicht richtig gemacht, aber es sollte bereits eine Überprüfung für die Länge plus Überprüfung für $ 2 $ oder was auch immer das Start-Bit für Hash-Werte ist.

Bearbeiten: Installieren Sie 2.45.1 von Loopback-Datenquelle-Jongleur und es sollte behoben werden.

+0

Danke .. Ich wusste das nicht! –

1

Hier ist meine "vollständige" Lösung zum Implementieren einer bestimmten remote-Methode updatePassword in einem LoopBack/StrongLoop - IBM-Projekt. Bitte überprüfen Sie, ob das Paket loopback-datasource-juggler eine höhere oder gleiche Version als 2.45.1 (npm list loopback-datasource-juggler) hat. Meine User Model MyUserModel genannt und erbt von dem Einbaumodell User:

"my-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'} 
    } 
); 

... 
}; 

"my-user-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.