JWT Strategy - kplian/pxp-nd GitHub Wiki

A Passport strategy for authenticating with a JSON Web Token.

1. Install

$ npm install passport-jwt

2. Configuration

Create file src/lib/auth/passport-jwt.js, with this configuration:

const JwtStrategy = require('passport-jwt').Strategy
const ExtractJwt = require('passport-jwt').ExtractJwt;
const pool = require('../PgPool');

// At a minimum, you must pass the `jwtFromRequest` and `secretOrKey` properties
const options = {
    jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
    secretOrKey: process.env.SECRET,  // string secret password
    algorithms: ['RS256']
};

// app.js will pass the global passport object here, and this function will configure it
module.exports = (passport) => {
    // The JWT payload is passed into the verify callback
    passport.use(new JwtStrategy(options, function (jwt_payload, done) {
        // We will assign the `sub` property on the JWT to the database ID of user
        pool.query('select * from pxp."user1" where id=$1', [jwt_payload.sub])
            .then(({ rows }) => {
                const user = rows[0];
                if (user) {
                    done(null, user);
                } else {
                    return done(null, false);
                }
            })
            .catch(err => done(err, false));
    }));
}

3. Routes

Use passport.authenticate(), specifying the 'jwt' strategy, to authenticate requests. Add routes in src/lib/auth/authRoutes.js:

router.post('/api/login/token', function(req, res, next) {
  pool.query('select * from pxp."user1" where username=$1', [req.body.username])
  .then(({ rows }) => {
      const user = rows[0];
      
      if (!user) { return res.status(400).send({ message: 'Invalid username or password'}); }
      const isValid = validPassword(req.body.password, user.hash, user.salt);
      
      console.log('user', isValid);
      if (isValid) {
        const tokenObject = issueJWT(user);
        return res.status(200).send({success: true, token:tokenObject.token, expiresIn: tokenObject.expires});
      } else {
        console.log('user', isValid);

        return res.status(400).send({ message: 'Invalid username or password'});
      }
  })
  .catch((err) => {
    return res.status(400).send(err);
  });
});

4. Use config

Finally import the configuration file into your main file before initializing passport:

// ...
require('./src/lib/auth/passport-jwt')(passport);
app.use(passport.initialize());
// ...