So I have a REST API written in Node.JS, MongoDB, and Express. I'm using passport and passport-jwt to authenticate using a JSON web token, but when I use different tokens for different user accounts, the request is saving the same user everytime.
Here is my authenticate endpoint in routes.js:
// Authenticate the user and get a JSON Web Token to include in the header of future requests.
apiRoutes.post('/authenticate', function(req, res) {
User.findOne({
email: req.body.email
}, function(err, user) {
if (err) throw err;
if (!user) {
res.send({ success: false, message: 'Authentication failed. User not found.' });
} else {
// Check if password matches
user.comparePassword(req.body.password, function(err, isMatch) {
if (isMatch && !err) {
// Create token if the password matched and no error was thrown
var token = jwt.sign(user, config.secret, {
//expiresIn: 10080 // in seconds
});
res.json({ success: true, token: 'JWT ' + token, _id: user._id });
} else {
res.send({ success: false, message: 'Authentication failed. Passwords did not match.' });
}
});
}
});
});
So, if the user credentials match in the database, it creates a new token and returns it. Then I put that token into the header of this endpoint:
// GET user
apiRoutes.get('/users', passport.authenticate('jwt', { session: false }), function(req, res) {
res.json(req.user);
});
I could authenticate a new user every time and get a different token every time, but the /users endpoint always returns the same user. Everything else is working in the API, the database is getting updated when registering new users and other things are being returned, but even with different tokens the same user is returned from passport. I know that I am putting the header in the right way in Postman with the key of Authorization and the value of the token with JWT in front of it, but I don't understand why this is happening.
Here is my passport.js if it matters:
var JwtStrategy = require('passport-jwt').Strategy;
var ExtractJwt = require('passport-jwt').ExtractJwt;
var User = require('../models/user');
var config = require('./main');
// Setup work and export for the JWT passport strategy
module.exports = function(passport) {
var opts = {};
opts.jwtFromRequest = ExtractJwt.fromAuthHeader();
opts.secretOrKey = config.secret;
passport.use(new JwtStrategy(opts, function(jwt_payload, done) {
User.findOne({id: jwt_payload.id}, function(err, user) {
if (err) {
return done(err, false);
}
if (user) {
done(null, user);
} else {
done(null, false);
}
});
}));
};
Any ideas?
So I figured out that it was displaying the first entry in the user document because the JWT was too big. So I changed the authenticate route to make the JWT out of just the user's id and username like so:
apiRoutes.post('/authenticate', function(req, res) {
User.findOne({
email: req.body.email
}, function(err, user) {
if (err) throw err;
if (!user) {
res.send({ success: false, response: 'Authentication failed. User not found.' });
} else {
// Check if password matches
user.comparePassword(req.body.password, function(err, isMatch) {
if (isMatch && !err) {
// Create token if the password matched and no error was thrown
var token = jwt.sign({id: user._id, username: user.username }, config.secret, {
expiresIn: 10080 // in seconds
});
res.json({ success: true, response: 'Authentication succeeded! User found.', token: 'JWT ' + token});
} else {
res.send({ success: false, response: 'Authentication failed. Passwords did not match.' });
}
});
}
});
});