Search code examples
node.jsexpressjwtpassport.jspassport-jwt

JWT Passport Not Returning User Data From Middleware


First time questioner, long time searcher. I'm having problems getting the user object to return from a Passport JWT verification call and I'm hoping someone can help figure out what's going wrong.

Here's my passport jwt configuration:

import jwtSecret from './jwtConfig';

const passport = require('passport'),
  localStrategy = require('passport-local').Strategy,
  User = require('../sequelize'),
  JWTstrategy = require('passport-jwt').Strategy,
  ExtractJWT = require('passport-jwt').ExtractJwt;

const opts = {
      jwtFromRequest: ExtractJWT.fromAuthHeaderWithScheme('JWT'),
      secretOrKey: jwtSecret.secret,
    };

    passport.use(
  'jwt',
  new JWTstrategy(opts, (jwt_payload, done) => {
    console.log('payload received');
    console.log(jwt_payload.id);
    try {
    User.findOne({
      where: {
        username: jwt_payload.id,
      },
    }).then(user => {
      console.log('user');
      console.log(user);
      if (user) {
        console.log(user);
        console.log('user found in db in passport');
        return done(null, user);
      } else {
        console.log('user not found in db');
        return done(null, false);
      }
    });
    } catch (err) {
      done(err);
    }
  }),
);

Here's my route where I'm calling the JWT Passport authentication:

import passport from 'passport';

module.exports = app => {
  app.get(
    '/findUser',
    passport.authenticate('jwt', { session: false }),
    (req, res, next) => {
      console.log(req.user);
      res.status(200).send({
        user: user,
        message: 'authenticated',
      });
    },
  );
};

And here's my server.js file, where I'm instantiating the routes.

import express from 'express';
import Cors from 'cors';
import bodyParser from 'body-parser';
import logger from 'morgan';
import passport from 'passport';
const app = express();

const API_PORT = process.env.API_PORT || 3000;

require('./config/passport');

app.use(Cors());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(logger('dev'));
app.use(passport.initialize());

require('./routes/loginUser')(app);
require('./routes/registerUser')(app);
require('./routes/findUsers')(app);

app.listen(API_PORT, () => console.log(`Listening on port ${API_PORT}`));

module.exports = app;

Maybe I'm going about using Passport JWT incorrectly, or calling it incorrectly, but each time I test it, I can see the token I'm creating, I can see user is found in the database, but it never gets returned when the return done(null, user) is called.

Each time I used Passport's local strategy to register and login the user and generate the JWT token with no problem, but for some reason I cannot get this user object back from Passport JWT.

Thanks for any help you can provide, I've been scouring the Internet, Github, Stack Overflow and the many blogs out there on this problem, but I haven't found a solution to my roadblock yet.

Follow up: I'm using React on the front end to make my call to server. The generated JWT token is set in local storage on the login call with the key 'JWT', it's then extracted for the next call to find the user's data like this:

async componentDidMount() {
    let accessString = localStorage.getItem('JWT');
    if (accessString === null) {
      this.setState({
        isLoading: false,
        error: true,
      });
    }
    await axios
      .get('http://localhost:3003/findUser', {
        params: {
          username: this.props.match.params.username,
        },
        headers: { JWT: accessString },
      })
      .then(response => {
        this.setState({
          first_name: response.data.first_name,
          last_name: response.data.last_name,
          email: response.data.email,
          username: response.data.username,
          password: response.data.password,
          isLoading: false,
          error: false,
        });
      })
      .catch(error => {
        console.log(error.data);
      });
  }

So perhaps, I'm not passing my JWT auth header in Axios correctly?


Solution

  • I have similar setup and am calling just done(null, user); without return.