Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

passport-local with node-jwt-simple

How can I combine passport-local to return a JWT token on successful authentication?

I want to use node-jwt-simple and looking at passport.js I am not sure how to go about.

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

Is it possible to return the token when calling done() ? Something like this... (just pseudo code)

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

If not, how can I return the token?

like image 237
cgiacomi Avatar asked Nov 26 '13 21:11

cgiacomi


People also ask

Does Passport local use JWT?

passport-local The local authentication strategy authenticates users using a username and password. The strategy requires a verify callback, which accepts these credentials and calls done providing a user. passport-jwt This module lets you authenticate endpoints using a JSON web token.

Should I use Passport or JWT?

Passport is Authentication Middleware for Node. JS, it is not for any specific method of authentication, the method for authentication like OAuth, JWT is implemented in Passport by Strategy pattern, so it means that you can swap the authentication mechanism without affecting other parts of your application.

Is JWT and Passport same?

JSON Web Token and Passport can be primarily classified as "User Management and Authentication" tools. JSON Web Token and Passport are both open source tools. It seems that Passport with 15.9K GitHub stars and 936 forks on GitHub has more adoption than JSON Web Token with 2.59K GitHub stars and 259 GitHub forks.


1 Answers

I figured it out!

First of all you need to implement the correct strategy. In my case LocalStrategy, and you need to provide your validation logic. For example sake let's use the one 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);     });   } )); 

the verify call back you provide function(username, password, done) will take care of finding your user and checking if the password matches (beyond the scope of the question and my answer)

passport.js expects several pieces for it to work, one is that you return the user in the strategy. I was trying to change that part of the code, and that was wrong. The callback expects false if the validation fails and an object (the validated user) if you are successful.

Now.... how to integrate JWT?

In your login route you will have to handle a successful auth or an unsuccessful one. And it is here that you need to add the JWT token creation. Like so:

(remember to disable the session, otherwise you will have to implement the serialize and deserialize functions. And you don't need those if you are not persisting the session, which you are not if you are using a token based auth)

From passport-local examples: (with the JWT token added)

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

And that is it! Now when you call /login and POST username and password (which should always be over SSL) the first code snippet above will try to find a user based on the username you provided and then check that the password matches (Of course you will need to change that to suit your needs).

After that your login route will be called and there you can take care of returning an error or a valid token.

Hope this will help someone. And if I have made any mistakes or forgot something let me know.

like image 175
cgiacomi Avatar answered Oct 15 '22 09:10

cgiacomi