imattacus imattacus - 22 days ago 7
Javascript Question

Passport JWT req.user is undefined in one of my routes

I'm having an absolute nightmare trying to set up JWT with my express app! Think I've got it mostly working now, I have a register route and login route that both work correctly and generate valid tokens and I have another route in my '/users' route that I test the authentication with and this is all fine. But I have another file containing routes for '/api' which is where the authentication is actually important and I have a similar test route that tries to access req.user (just like I do in my other route) but it seems like req.user is undefined. Through some debugging it looks like the user is in req.account which is very odd and I don't understand why its not in req.user

I define my jwt strategy in /config/passport.js

'use strict';
const User = require('../models/user'),
config = require('./main'),
JwtStrategy = require('passport-jwt').Strategy,
ExtractJwt = require('passport-jwt').ExtractJwt;

//exported to be used by passport in server set up
module.exports = function (passport) {
const jwtOptions = {
// Telling Passport to check authorization headers for JWT
jwtFromRequest: ExtractJwt.fromAuthHeader(),
// Telling Passport where to find the secret
secretOrKey: config.secret
};

const jwtLogin = new JwtStrategy(jwtOptions, function(payload, done) {
User.findById(payload._id, function(err, user) {
if (err) { return done(err, false); }

if (user) {
done(null, user);
} else {
done(null, false);
}
});
});

passport.use(jwtLogin);

}


passport is passed as an argument to this and then initialised in the main express file

here is the /users route file, this works fine. sending a GET request to /users/isAuth with Authorization header and 'JWT ' works fine and I get my username sent back to me

"use strict";
const express = require('express'),
router = express.Router(),
jwt = require('jsonwebtoken'),
User = require('../models/user'),
config = require('../config/main'),
passport = require ('passport');

function generateToken(user) {
return jwt.sign({_id: user._id}, config.secret, {
expiresIn: 10080
});
}
.
. Here are routes for login and register they perform as expected
. and work fine
.
/* ==================================
Test Authentication Route
================================== */
router.get('/isAuth', passport.authenticate('jwt', { session: false }), function(req, res) {
console.log(req.user);
res.json({username: req.user.username});
});



module.exports = router;


In this file though, for the api routes sending a request to GET /api/testAuth exactly the same as before with the same token and the same headers I get back no req.user and in the console I see that req.user is undefined. But in the console there does seem to be the user object just as req.account? I don't understand what is happening here hopefully someone can help!

"use strict";
const express = require('express'),
router = express.Router(),
jwt = require('jsonwebtoken'),
Server = require('../models/server'),
passport = require('passport');

// Test route to see if logged in user is matt
router.get('/testAuth', passport.authorize('jwt', { session: false }), function(req, res) {
console.log(req.user);
if (req.user) {
if(req.user.username == "matt") {
res.send("You are matt!");
} else {
res.send("You are not matt!");
}
} else {
res.send("no req.user");
}

})

module.exports = router;

Answer

You are using passport.authorize in your testAuth route, this is for users that are already logged in and have session information. Since you are not using session storage you do not have a persistent req.user object and so should use passport.authenticate on all routes

http://passportjs.org/docs/authorize

Comments