2013-11-26 11 views
81

Wie kann ich Pass-Local kombinieren, um ein JWT-Token bei erfolgreicher Authentifizierung zurückzugeben?Pass-Local mit Node-JWT-einfach

Ich möchte node-jwt-simple verwenden und Blick auf passport.js Ich bin mir nicht sicher, wie es geht.

var passport = require('passport') 
    , LocalStrategy = require('passport-local').Strategy; 

passport.use(new LocalStrategy(
    function(username, password, done) { 
    User.findOne({ username: username }, function(err, user) { 
     if (err) { return done(err); } 
     if (!user) { 
     return done(null, false, { message: 'Incorrect username.' }); 
     } 
     if (!user.validPassword(password)) { 
     return done(null, false, { message: 'Incorrect password.' }); 
     } 
     return done(null, user); 
    }); 
    } 
)); 

Ist es möglich, das Token beim Aufruf von done() zurückzugeben? So etwas wie dies ... (nur Pseudo-Code)

if(User.validCredentials(username, password)) { 
    var token = jwt.encode({username: username}, tokenSecret); 
    done(null, {token : token}); //is this possible? 
} 

Wenn nicht, wie kann ich das Token zurückgeben?

Antwort

116

Ich habe es herausgefunden!

Zuerst müssen Sie die richtige Strategie implementieren. In meinem Fall LocalStrategy, und Sie müssen Ihre Validierungslogik bereitstellen. Zum Beispiel lassen Sie uns den im Pass-lokalen verwenden.

var passport = require('passport') 
    , LocalStrategy = require('passport-local').Strategy; 

passport.use(new LocalStrategy(
    function(username, password, done) { 
    User.findOne({ username: username }, function(err, user) { 
     if (err) { return done(err); } 
     if (!user) { 
     return done(null, false, { message: 'Incorrect username.' }); 
     } 
     if (!user.validPassword(password)) { 
     return done(null, false, { message: 'Incorrect password.' }); 
     } 
     return done(null, user); 
    }); 
    } 
)); 

die überprüfen Rückruf Ihnen function(username, password, done) wird darauf achten, Ihre Benutzer zu finden und zu überprüfen, ob das Passwort stimmt, (über den Rahmen der Frage und meine Antwort)

passport.js für sie mehrere Stücke erwartet Um zu arbeiten, ist einer, dass Sie den Benutzer in der Strategie zurückgeben. Ich habe versucht, diesen Teil des Codes zu ändern, und das war falsch. Der Rückruf erwartet false, wenn die Validierung fehlschlägt und object (der validierte Benutzer), wenn Sie erfolgreich sind.

Jetzt .... wie JWT zu integrieren?

In Ihrer Login-Route müssen Sie eine erfolgreiche oder eine fehlgeschlagene Authentifizierung durchführen. Und hier müssen Sie die JWT-Token-Erstellung hinzufügen. Wie so:

(Denken Sie daran, die Sitzung zu deaktivieren, sonst müssen Sie die Serialize und Deserialize Funktionen implementieren. Und Sie brauchen diese nicht, wenn Sie nicht die Sitzung beibehalten, die Sie nicht sind, wenn Sie eine verwenden Token basiert auth)

Von Pass lokale Beispiele: (mit der JWT-Token hinzugefügt)

// POST /login 
// This is an alternative implementation that uses a custom callback to 
// achieve the same functionality. 
app.post('/login', function(req, res, next) { 
    passport.authenticate('local', function(err, user, info) { 
    if (err) { return next(err) } 
    if (!user) { 
     return res.json(401, { error: 'message' }); 
    } 

    //user has authenticated correctly thus we create a JWT token 
    var token = jwt.encode({ username: 'somedata'}, tokenSecret); 
    res.json({ token : token }); 

    })(req, res, next); 
}); 

Und das ist es! Jetzt, wenn Sie/login und POST Benutzername und Passwort (die immer über SSL sein sollte) aufrufen, wird das erste Code-Snippet versuchen, einen Benutzer anhand des von Ihnen angegebenen Benutzernamens zu finden und dann zu überprüfen, ob das Passwort übereinstimmt (Natürlich müssen Sie ändere das nach deinen Bedürfnissen).

Danach wird Ihre Login-Route aufgerufen und Sie können sich um einen Fehler oder ein gültiges Token kümmern.

Hope this jemand helfen. Und wenn ich Fehler gemacht oder etwas vergessen habe, lass es mich wissen.

+2

Cool, danke für die Buchung, wie Sie gelöst it :) – robertklep

+3

Passports [BasicStrategy] (http://passportjs.org/guide/basic-digest/) oder DigestStrategy sind zwei weitere Optionen. Es scheint jedoch keinen großen Unterschied zwischen Basic- und Local-Strategien zu geben, da beide keine Sessions benötigen - nur dass Local nach Redirect-URLs fragt (was es weniger API-freundlich macht). – funseiki

+1

Hey @cgiacomi könnten Sie ein Beispiel für eine Route geben, die das Token überprüft? –

18

Dies ist eine großartige Lösung, ich möchte nur hinzufügen:

var expressJwt = require('express-jwt'); 

app.use('/api', expressJwt({secret: secret})); 

Ich mag verwenden "Express-jwt" das Token zu validieren .

btw: Dieser Artikel ist toll zu erfahren, wie das Token in der Client-Seite zu handhaben, mit Schräg, um es mit jeder Anfrage zu senden zurück

https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/

+2

Ich habe 'express-jwt' nur verwendet, um Authentifizierung zu tun, aber das Durchlesen der Dokumentation anderer Pakete wie 'pass-jwt', ich denke, ich werde bei' express-jwt' bleiben. Viel einfacher, viel schöner IMO – bobbyz

+0

Nur ein FYI Express-JWT bietet keine Unterstützung für Refresh-Token. – user3344977