2017-01-02 4 views
0

Ich habe eine grundlegende Mungo-Authentifizierung, mit bcryptjs Hash-Passwörter. Sowohl bcrypt und mongoose versprechen zurück. In meinem routes.js ich das folgende Skript haben, die nach dem Auffinden der Benutzer in der db klemmt:Wie ruft man eine Funktion auf, die ein Versprechen auf ein Ergebnis eines Versprechens zurückgibt?

routes.post('/auth', (req, res)=> { 
    User.findOne({'local.username': req.body.username}) 
     .then(
      user=> Promise.all([user, user.validate(req.body.password)]) 
     ) 
     .then(
      results => { 
       console.log(results); 
       res.json({token: jwt.sign({id: results[0]._id}, config.secret)}); 
      } 
     ) 
     .catch(
      err=> console.log(err) 
     ); 
}); 

Wie man sehen kann ich den Benutzer zu finden, und dann versuchen, die Validate-Methode zu nennen (die aufgerufen wird) , aber es löst weder das Versprechen noch einen Fehler. In meinem user.js die meine UserSchema definiert habe ich diesen Code Passwörter vergleichen:

UserSchema.methods.validate = function (password) { 
    return bcrypt.compare(password, this.local.password); 
}; 

Dies genannt wird, aber die zurückgegebene Versprechen scheint, wie es verschwindet, ist es nicht gelöst wird, wird die Ergebnisse Variable nie protokolliert.

Eine weitere Sache, wenn ich Benutzer Validierungscode zu dieser bearbeiten:

UserSchema.methods.validate = function (password) { 
    return bcrypt.compare(password, this.local.password).then(
     results => { 
      console.log(results) 
     } 
    ) 
}; 

ich wahr bekommen angemeldet zu trösten, so muss es funktionieren, aber ich will nicht mein Versprechen hier lösen, ich will den .then (...) in meinem Router anzubringen, ist das nicht möglich?

Was mache ich falsch?

UPDATE:

Wenn ich das vergleichen Methode in dem routes.js setzte es funktioniert, aber das ist nicht das, was ich tun will, ich will es in dem user.js halten, aber ich dachte, Dies könnte auf das Problem hinweisen, das ich immer noch nicht sehen kann. Ich schätze ich muss dann sofort auf das Versprechen eingehen, aber ich verstehe nicht warum.

User.findOne({'local.username': req.body.username}) 
     .then(
      user=> Promise.all([user, bcrypt.compare(req.body.password,user.local.password)]) 
     ) 
     .then(
      results => { 
       console.log(results); 
       res.json({token: jwt.sign({id: results[0]._id}, config.secret)}); 
      } 
     ) 
     .catch(
      err=> console.log(err) 
     ); 
+0

'' Promise.all ([user, user.validate (req.body.password)]) '' 'sollte sein' Promise.all ([Promise.resolve (Benutzer), user.validate (req.body.password)]) '' – MatthieuLemoine

+0

@MatthieuLemoine Ja, das scheint vernünftig, aber versuchte es und es funktioniert nicht: S – godzsa

+0

Nicht sicher, aber ich denke, Ihre validierte Methode sollte Lösen Sie auch das Versprechen. –

Antwort

-1

Sie tun nichts mit der Promise.all rufen Sie in der dann.

Statt

user=> Promise.all([user, user.validate(req.body.password)]) 

Sie sollten dann:

user.validate(req.body.password) 
.then(results => { 
    // Do stuff with results here... 
}); 
+1

Ich denke, das ist das gleiche, weil Promise.all() eine Zusage zurückgibt, die von .then() behandelt wird – godzsa

+0

Und das funktioniert nicht – godzsa

+1

Er gibt die 'Promise.all (...)' aus dem Rückruf, das heißt genug zu tun. – Bergi

0

Zunächst einmal, warum hier mit Promise.all? Vor allem sehe ich nicht die Notwendigkeit, etwas wie Promise.resolve(user) zu tun. Ohne zu wissen, wie user.validate funktionieren, würde ich es gerne schreiben

routes.post('/auth', (req, res)=> { 
    let userId 

    User.findOne({'local.username': req.body.username}) 
    .then(user => { 
     userId = user._id 
     return user.validate(req.body.password) 
    }) 
    .then(results => { 
     console.log(results); 
     res.json({token: jwt.sign({id: userId}, config.secret)}); 
    }) 
    .catch(err => console.log(err)) 
}); 
+0

Ich habe das versucht. Es funktioniert nicht für mich, deshalb versuchte ich später Promise.all(), das funktioniert auch nicht – godzsa

+0

Warum 'Promise.all'? Denn das ist ein [viel besseres Muster] (http://stackoverflow.com/a/28250704/1048572) als [die hässliche globale Variable 'userId'] (http://stackoverflow.com/a/28250700/1048572). – Bergi

+0

Würde teilweise mit Ihnen übereinstimmen. Würden sich darüber streiten, was hässlicher ist, eine Bereichsvariable erstellen, um den Handler zu routen oder ein Versprechen zu erstellen, wenn es nicht benötigt wird. – Srle

0

Ich fand heraus, dass das Problem mit Mungo ist. Es umhüllt die Modulmethoden und verspricht irgendwo "verloren zu gehen". Die Lösung hierfür besteht darin, eine Synchronisierungsvergleichsmethode zu verwenden oder einen Rückruf bereitzustellen.

Auch habe ich ein Problem mit diesem auf GitHub: https://github.com/Automattic/mongoose/issues/4856

Verwandte Themen