3
votes

I am experiencing a strange bug or error in my code. I have setup an auth api on node server, using passportjs as my middleware and passport-jwt as my strategy.

My passport setup looks like this

//add jwt strategy to passport
var JwtStrategy = require('passport-jwt').Strategy;
var ExtractJwt = require('passport-jwt').ExtractJwt;

var User = require('../models/user');
var configDB = require('../config/database');

module.exports = function(passport) {
    var opts = {};
    opts.secretOrKey = configDB.secret;
    opts.jwtFromRequest = ExtractJwt.fromAuthHeader();
    passport.use(new JwtStrategy(opts, function(jwt_payload, done) {
        //find user with give jwt payload id
        User.findOne({
            id: jwt_payload.id
        }, function(err, user) {
            if(err) {
                return done(err, false);
            }
            if(user) {
                done(null, user);
            } else {
                done(null, false);
            }
        });
    }));
};

then, my protected route:

apiRoutes.get('/account', passport.authenticate('jwt', {session: false}), function(req, res) { 

    console.log(req.user.nickname); //returns user1 no matter what JWT I supply with request
    console.log(jwt.decode(getToken(req.headers), configDB.secret)).nickname; //decodes user from token correctly
    ..do other stuff
});

Why does passport sets req.user with the same user everytime, no matter what Token I supply in Authorization header ? Thanks

4

4 Answers

2
votes

Solved, this line caused problem:

User.findOne({
  id: jwt_payload.id
...

both ids should be _id :)

2
votes

@BlueBallPanda, to answer your question with passport.js JWT authentication strategy I would like to show the structure of JWT_PAYLOAD object that you use in line:

...  
passport.use(new JwtStrategy(opts, function(jwt_payload, done) { 
...
}));

As a reference example here below is output of JWT_PAYLOAD object, you can see its structure, which can actually easily confuse:

JWT_PAYLOAD:  { '$__':
   { strictMode: true,
     selected: {},
     getters: {},
     _id: '7987930e36333b5634bb5577',
     wasPopulated: false,
     activePaths: { paths: [Object], states: [Object], stateNames: [Array] },
     pathsToScopes: {},
     emitter: { domain: null, _events: {}, _eventsCount: 0, _maxListeners: 0 } },
  isNew: false,
  _doc:
   { __v: 0,
     password: '$2a$10$12GRB1vGbkl3XfGY.r81SuASyK/cfsp85fk92B3N6eSRO6GVy1TSW',
     email: '[email protected]',
     _id: '7987930e36333b5634bb5577' },
  '$init': true,
  iat: 1502061031,
  exp: 1502071111 }

So to grab the user ID in order to extract from DB on JWT check, just reference it like that:

 User.findOne({
        id: jwt_payload.$__._id
    }

or like that:

 User.findOne({
        id: jwt_payload.$__._doc._id
    }

Hope this clears out the buggy situation you have experienced.

0
votes

I solve this problem with this function:

var JwtStrategy = require(‘passport-jwt’).Strategy,
ExtractJwt = require(‘passport-jwt’).ExtractJwt;

// load up the user model
var User = require(‘../models/user’);
var config = require(‘../config/database’); // get db config file

module.exports = function(passport) {
    var opts = {};
    opts.jwtFromRequest = ExtractJwt.fromAuthHeader();
    opts.secretOrKey = config.secret;
    passport.use(new JwtStrategy(opts, function(jwt_payload, done) {
        done(null, jwt_payload._doc);
    }));
};

_doc have the data user.

0
votes

Add the where clause solved my problem:

let user = await User.findOne({ where: { id: JWTPayloads.id } });