14

My middleware code is:

exports.isAuthenticated = (req, res, context) => {
  return new Promise((resolve, reject) => {
    return passport.authenticate('jwt',{session: false}, (err, user, info) => {
      if(err) {
        res.status(500).send({message: 'Internal Server Error'})
        return resolve(context.stop);
      }

      if(user) {
        return resolve(context.continue);
      } else {
        res.status(401).send({message: 'Unauthorized'})

        return resolve(context.stop)
      }
    })(req, res);
  }); 
}

My epilogue code is:

// Data plan REST API
const dataplan = epilogue.resource({
  model: global.db.DataPlan,
  endpoints: ['/api/dataplan', '/api/dataplan/:id']
});

dataplan.all.auth(middleware.isAuthenticated)
dataplan.use(require('./epilogue/dataplan.js'))

And my dataplan.js is:

module.exports = {
    list: {
      auth: async function (req, res, context) {
        console.log(req.user)
        return context.continue
      },
      send: {
       ....

But my req.user is empty in my list.auth. What am I doing wrong?

Shamoon
  • 41,293
  • 91
  • 306
  • 570
  • I don't think you can use `async` functions here, because it seems to based on express which expects normal function to be middleware – Tarun Lalwani May 21 '18 at 20:10
  • Try using this package that will allow you to use async in your express functions : https://www.npmjs.com/package/express-async-errors – HRK44 Jul 10 '18 at 13:10
  • Have you tried printing something in your middleware to make sure it is called when you expect it to be? – Telokis Sep 11 '18 at 09:25

1 Answers1

2

TL;DR

passport.authenticate doesn't set req.user if you provide a callback to it. You have to set it yourself.

Solution

I was able to reproduce your case and the behavior showed up as expected.

In order to fix it, I had to update your auth middleware like so:

exports.isAuthenticated = (req, res, context) => {
  return new Promise((resolve, reject) => {
    return passport.authenticate('jwt',{session: false}, (err, user, info) => {
      if(err) {
        res.status(500).send({message: 'Internal Server Error'})
        return resolve(context.stop);
      }

      if(user) {
        req.user = user; // Manually set the user in req
        return resolve(context.continue);
      } else {
        res.status(401).send({message: 'Unauthorized'})

        return resolve(context.stop)
      }
    })(req, res);
  }); 
}

I manually assign user to req.user when authentication is successful. This properly fixes the issue.

Why does this happen?

By looking at the passport source code I notice that the passport.authenticate function will short circuit itself if the user provides a callback himself.
This means that you have to set the value yourself.

Telokis
  • 3,399
  • 14
  • 36