Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using passport-jwt and epilogue, my req.user is empty

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?

like image 603
Shamoon Avatar asked May 17 '18 14:05

Shamoon


People also ask

Should I use Passport or JWT?

JSON Web Token and Passport can be primarily classified as "User Management and Authentication" tools. JSON Web Token and Passport are both open source tools. It seems that Passport with 15.9K GitHub stars and 936 forks on GitHub has more adoption than JSON Web Token with 2.59K GitHub stars and 259 GitHub forks.

Can I use Passport with JWT?

A Passport strategy for authenticating with a JSON Web Token. This module lets you authenticate endpoints using a JSON web token. It is intended to be used to secure RESTful endpoints without sessions.


1 Answers

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.

like image 79
Telokis Avatar answered Oct 22 '22 00:10

Telokis