1

I am trying to write API's of which some of them has role based authorization. Further I am using JWT for authentication for my API's.

Below is the code, I am trying to write. However, when I hit "/user/:email" endpoint, authorize function is not getting called. Always, getUser function is getting called. I was in an assumption that at first authorize function should be called followed by getUser.

Can someone enlighten me why authorize function is not getting called when I hit "/user/:email" endpoint? What wrong am I doing here? And how can I correctly handle this scenario?

var express = require('express')
var router = express.Router();
var expressJwt = require('express-jwt');

var authorize = function(role){     
  expressJwt({secret:'secretKey'}, (req, res, next) =>{
    console.log('req.role is', req.role);
    if(req.role === role){
       next();
    }else{
       res.status(403).send({message: 'Unauthorized'});
    }
  })  
}

var getUser = function(req,res,next){
    res.status(200).send("Hello user");
}

router.get('/user/:email', authorize('Admin'), getUser); 
Sreehari
  • 1,328
  • 11
  • 29
  • I would say your middleware just returns some functions inside an array. These brackers are strange – Rashomon Mar 16 '19 at 18:04
  • @Rashomon: If I remove square brackets inside authorize function, I am getting a compiler/interpreter error as "Error: Route.get() requires a callback function but got a [object Undefined]". – Sreehari Mar 16 '19 at 18:14

1 Answers1

1

authorize is called when the application starts up, not when you hit "/user/:email". Calling authorize('Admin') just returns undefined which will not cause the console.log being executed, neither when "/user/:email" is hit.

I think what you want to achieve is applying multiple callbacks sequentially to one route.

See here

So, authorize('Admin') should return a middleware (also called callback), such as:

return expressJwt({secret:'secretKey'}, (req, res, next) =>{...})
  • To some extent you are correct, I have to apply multiple callback sequentially to one route. But how can I achieve this? How can I pass "Admin" role into the callback function authorize? – Sreehari Mar 16 '19 at 18:40
  • @Sreehari - sorry what's the point of passing role from request to authentication method? Shouldn't role be read from the authenticated user? in which case you would handle authorization after you fetch the user – Milan Mar 16 '19 at 18:52
  • @Milan: I have roles like 'Admin', 'customer', 'partner'. Authentication simply authenticates all kinds of users and generates JWT token. Now, some of the routes are accessible only to 'Admin'. So I need to authorize user before route Handler is executed. How can I do it then? – Sreehari Mar 16 '19 at 18:59
  • 1
    @Sreehari - well if you want to check if user of the certain JWT token has certain permission, you can try using `express-jwt-permissions` package in conjunction with `express-jwt`. – Milan Mar 16 '19 at 19:26
  • @Milan: Thanks Milan. express-jwt-permissions seems to a good one. I will try this. – Sreehari Mar 19 '19 at 16:32