2013-11-26 11 views
81

Come è possibile combinare passport-local per restituire un token JWT in caso di autenticazione riuscita?passport-local con node-jwt-simple

Voglio usare node-jwt-simple e guardando passport.js Non so come fare.

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

È possibile restituire il token quando si chiama done()? qualcosa di simile ... (basta pseudo codice)

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

Se no, come posso tornare il segno?

risposta

116

L'ho capito!

Prima di tutto è necessario implementare la strategia corretta. Nel mio caso, LocalStrategy, e devi fornire la tua logica di convalida. Per esempio, usiamo quello in passport-local.

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

la chiamata verificare di nuovo che fornisci function(username, password, done) si prenderà cura di trovare il vostro utente e verifica se la password corrisponde (al di là della portata della domanda e la mia risposta)

passport.js prevede diversi pezzi per esso per funzionare, uno è quello di restituire l'utente nella strategia. Stavo cercando di cambiare quella parte del codice, e quello era sbagliato. La callback si aspetta false se la convalida fallisce e un object (l'utente convalidato) se si ha successo.

Ora .... come integrare JWT?

Nel percorso di accesso è necessario gestire un'autenticazione riuscita o una non riuscita. Ed è qui che è necessario aggiungere la creazione di token JWT. In questo modo:

(ricordarsi di disabilitare la sessione, altrimenti si dovranno implementare le funzioni serializza e deserializza e non sono necessari quelli se non si continua la sessione, cosa che non si è se si sta utilizzando un token di autenticazione basato)

Da esempi passaporto locale: (con il token JWT aggiunto)

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

E che è! Ora quando chiami/login e nome utente e password POST (che dovrebbe sempre essere su SSL) il primo frammento di codice sopra cercherà di trovare un utente in base al nome utente che hai fornito e quindi verifica che la password corrisponda (ovviamente dovrai cambialo in base alle tue esigenze).

Successivamente verrà chiamato il percorso di accesso e lì sarà possibile restituire un errore o un token valido.

Spero che questo aiuti qualcuno. E se ho fatto degli errori o ho dimenticato qualcosa fammelo sapere.

+2

Cool, grazie per la pubblicazione come hai risolto it :) – robertklep

+3

Passport [BasicStrategy] (http://passportjs.org/guide/basic-digest/) o DigestStrategy sono altre due opzioni. Non sembra esserci un'enorme differenza tra le strategie di base e locali, tuttavia, dal momento che nessuno dei due ha bisogno di sessioni per funzionare - solo che Local richiede URL di reindirizzamento (rendendo leggermente meno API friendly). – funseiki

+1

Hey @cgiacomi potresti dare un esempio di un percorso che controlla il token? –

18

Questa è una grande soluzione, voglio solo aggiungere questo:

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

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

Mi piace usare "express-JWT" per convalidare il token .

btw: questo articolo è grande per imparare a gestire il token nel lato client, utilizzando angolare, al fine di inviare indietro con ogni richiesta

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

+2

Ho usato solo 'express-jwt' per fare l'autenticazione, ma ho letto la documentazione di altri pacchetti come 'passport-jwt', penso che starò attaccato a 'express-jwt'. Molto più semplice, molto più bello IMO – bobbyz

+0

Solo un FYI express-jwt non fornisce supporto per i token di aggiornamento. – user3344977