auth0 / express-jwt

connect/express middleware that validates a JsonWebToken (JWT) and set the req.user with the attributes
MIT License
4.49k stars 444 forks source link

JWT is resetting my previously set req.user #170

Open ghost opened 7 years ago

ghost commented 7 years ago

node(7.4.0) - express (4.15.2) express-jet (5.1.0)

in my user.route.js , I am using router.param('userId',..) to find and load the use into req.user

    import express from 'express';
import expressJwt from 'express-jwt';
import validate from 'express-validation';
import paramValidation from '../../../config/param-validation';
import userCtrl from '../controllers/user.controller';
import config from '../../../config/config';

const router = express.Router(); // eslint-disable-line new-cap
...
router.route('/:userId/roles')
  /** POST /api/users/:userId/roles - Add a role to a user*/
  .post(expressJwt({ secret: config.jwtSecret }), userCtrl.addRole);
....
/** Load user when API with userId route parameter is hit */
router.param('userId', userCtrl.load);

export default router;

In my user.conytroller, the load() function, search and append the user to request into req.user

import httpStatus from 'http-status';
import APIError from '../../helpers/APIError';
import User from '../../models/user.model';

/**
 * Load user and append to req.
 */
function load(req, res, next, id) {
  User.get(id)
    .then((user) => {
      req.user = user; // eslint-disable-line no-param-reassign
      // req.user is now: {"_id":"593031798022f95cf25a3f3e","username":"KK123","password":"KKpassword",
      // "email":"kk123@example.com","mobileNumber":"9999999999","__v":0,"createdAt":"2017-06-01T15:23:37.509Z","roles":[]}
      next();
    })
    .catch((e) => {
        if (e.name === 'CastError') {
          const err = new APIError('Cast Error', httpStatus.BAD_REQUEST, true);
          next(err);
        } else {
          const err = new APIError('User not found', httpStatus.NOT_FOUND, true);
          next(err);
        }
      });
}

NOW, if I perform the POST /api/users/:userId/roles which first authenticate the user with jet, the req.user is REPLACED with

req.user:  { username: 'react', iat: 1496330617 }

And my pre-loading is not anymore valide, so the POST

/**
 * Add role to a user
 * @returns {User}
 */
function addRole(req, res, next) {
  const user = req.user;   <= t it's { username: 'react', iat: 1496330617 } not the user doc
  // check if existing role
  user.roles.push(req.body);
  user.save()
    .then((savedUser) => {
      res.json(savedUser);
    })
    .catch(() => {
      const err = new APIError('Cannot save role', httpStatus.UNPROCESSABLE_ENTITY, true);
      next(err);
    });
}

This runs well if I do not use jet ... of course... what do you suggest ? thanks

allspark commented 7 years ago

change the requestProperty in Express-JWT

from docs: jwt({secret: publicKey, requestProperty: 'auth' });