Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle errors with Express-JWT

I am trying to incorporate the express-jwt library and I do not quite understand how it's error handling works.

The documentation says:

Error handling

The default behavior is to throw an error when the token is invalid, so you can >add your custom logic to manage unauthorized access as follows:

    app.use(function (err, req, res, next) {
      if (err.name === 'UnauthorizedError') {
        res.status(401).send('invalid token...');
      }
    });

But I am confused how that works. If I have a simple req res situation, and I want to call next if the token is valid, or call next with an error if it is not, where to I put that app.use function?

For instance, here is my code:

router.post('/', expressJwt({  
  secret: jwtSecret,     
  credentialsRequired: false  
}), (req, res, next) => {   
  databaseController.findUser(req.user.email, (err, user) => {          
    if (err) {          
      return next(err)      
    }                        
    res.json(user)     
  })         
})

The err here would come from my DB call, not from the express-jwt validation. Any help is appreciated.

like image 983
Startec Avatar asked Dec 05 '16 08:12

Startec


People also ask

How do you handle JWT error?

catch any error from jwt-simple , then throw an error with a custom error code using http-errors or boom, and then return the appropriate JSON to your user with the help of an error handler middleware.

What is a JWT error?

This error occurs if the JSON Web Token (JWT) specified in the <Source> element of the Decode JWT policy is malformed, invalid or otherwise not decodable. A properly structured JWT should contain a header, payload and signature in the following format: header.

Does Express Session use JWT?

Express session using JWT. Drop-in replacement of express-session with enhanced security (blog post). Compared to the original express-session , this fork: Uses JWT as session tokens.


3 Answers

Another way is you could place the middleware with app.use to scan all the routes for a valid jwt in the header or the query string. Any public endpoints can be exempted using the unless keyword. Ex:

app.use(expressjwt({credentialsRequired: true, secret: config.TOKEN_SECRET, requestProperty: 'user'}).unless({path: config.PUBLIC_URLs}));

app.use(function(err, req, res, next) {
    if(err.name === 'UnauthorizedError') {
      res.status(err.status).send({message:err.message});
      logger.error(err);
      return;
    }
 next();
});
like image 187
Hanu Avatar answered Oct 15 '22 07:10

Hanu


this is my solution for individual routes.

function UseJwt(){
    return [
        jwtExpress({ secret: configuration.jwtSecret, algorithms: ['HS256'] }),
        function(err, req, res, next){
            res.status(err.status).json(err);
        }
    ]
}

usage...

app.get(`/${prefix}/:user_id`,
        ...UseJwt(),
        async function (req, res) {           
           // handle your code here.
        }
)
like image 41
Carlos Arturo Alaniz Avatar answered Oct 15 '22 06:10

Carlos Arturo Alaniz


You can create an express middleware just before the code you use to start express server.

// Global error handler that takes 4 arguments and ExpressJS knows that
app.use((err, req, res, next) => {
    res.status(err.status).json(err);
});
app.listen(3000);

I use that for apps use REST but you can use the same approach and modify what should happen based on your needs. If you use Jade template for instance then you need to populate the template with the data you want to show to end user and log the rest on your log file.

app.use((err, req, res, next) => {
    res.locals.status = status;
    res.render('error')
});
like image 21
Mohammed Ramadan Avatar answered Oct 15 '22 06:10

Mohammed Ramadan