Search code examples
javascriptnode.jsexpressauth0express-jwt

express-jwt can't access req.user from routes directory


New to express...

I can access req.user when I handle requests inside my app.js file. However, routes that I define inside my routes folder (specifically routes/users.js) don't have req.user even though I authenticate them in app.js (app.use('/users', authenticate);. As I mentioned, I am new to express so I am probably configuring something incorrectly. Any tips are much appreciated! Let me know if this is unclear or you need more information. Thanks!

app.js

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var dotenv = require('dotenv');
var jwt = require('express-jwt');
var cors = require('cors');
var http = require('http');

var routes = require('./routes/index');
var users = require('./routes/users');

var app = express();
var router = express.Router();

dotenv.load();

var authenticate = jwt({
  secret: new Buffer(process.env.AUTH0_CLIENT_SECRET, 'base64'),
  audience: process.env.AUTH0_CLIENT_ID
});

app.use(cors());
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());


app.use('/', routes);
app.use('/users', users);
app.use('/users', authenticate);
app.use('/secured', authenticate);


app.get('/ping', function(req, res) {
  res.send("All good. You don't need to be authenticated to call this");
});


app.get('/secured/ping', function(req, res) {
  // req.user works here!
  res.status(200).send("All good. You only get this message if you're authenticated");
});

var port = process.env.PORT || 3001;

http.createServer(app).listen(port, function (err) {
  console.log('listening in http://localhost:' + port);
});

module.exports = app;

routes/users.js

var models  = require('../models');
var express = require('express');
var router  = express.Router();

router.post('/', function(req, res) {
  // req.user = undefined
  console.log("user: " + req.user.sub)
  models.User.findOrCreate({
    where: {tokenId: req.user.sub},
    defaults: {
      name: req.body.name,
      tokenId: req.user.sub,
      points: 0
    }
  }).then(function(user) {
    res.json(JSON.stringify(user));
  });
});

module.exports = router;

Solution

  • I think the issue is with the ordering of the following code in app.js

    //some code
    app.use('/users', users);
    app.use('/users', authenticate);
    //some code
    

    Nodejs works in sequential manner. So, it will read the users route in routes/users.js first and then authenticate function. In this way, there would undefined req.user as authenticate function is called afterwards.

    If you try to access req.user after app.use('/users', authenticate), it won't be undefined ( express-jwt works properly).

    Now, if you change the code to

    //some code
    app.use('/users', authenticate);
    app.use('/users', users);
    //some code
    

    then, it will authenticate the user and put the user object in req.user and can be accessible afterwards.

    Hope it works for you. Let me know, if there is any issue.