Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Role based authorization with express-jwt?

I am using express-jwt to protect my API endpoint so that only authenticated users can access my APIs. Now I want to also protect my APIs based on user's role too. For example, user can only access some APIs if they are admin, some others if they are super admin, etc. How can I achieve this? I found in express-jwt github doc this code snippet:

app.get('/protected',
  jwt({secret: 'shhhhhhared-secret'}),
  function(req, res) {
    if (!req.user.admin) return res.sendStatus(401);
    res.sendStatus(200);
  });

It looks like this code is doing authorization in API controller function. Is it the only and recommended way? Are there any better ways to do this? Any advices about best practices for this?

like image 424
congtrungvnit Avatar asked Mar 31 '16 17:03

congtrungvnit


People also ask

What is the difference between JWT and express authentication?

We already discussed this in detailed in our previous article Handling Authentication in Express.js. On the other hand with JWT, when the client sends an authentication request to the server, it will send a JSON token back to the client, which includes all the information about the user with the response.

Does express REST API support token based authentication with JWT (jsonwebtoken)?

In this tutorial, we’re gonna build a Node.js Express Rest API example that supports Token Based Authentication with JWT ( JSONWebToken ). You’ll know:

How do I get a JWT token from authservice?

Update AuthService to issue a JWT access token. In the login method, it creates a payload that will be a part of the JWT token and signs it. Create constants.ts in the auth folder where a JWT signing key will be stored.

How to list user roles in a JWT payload?

When creating the JWT, you can provide your own payload as a private claim. E.g.: { "sub": "1234567890", "name": "John Doe", "admin": true, "superUser": false } Same way you can perhaps list a set of user roles for the logged in user { "sub": "1234567890", "name": "John Doe", "roles": [ "ADMIN", "SUPERUSER" ] }


1 Answers

Is it the only and recommended way?

pretty much, yeah.

this isn't a "controller function", though. this is an example of middleware, which is what you want to use in this case.

a more complete example would be:


var router = new express.Router();

// process jwt stuff
var processjwt = jwt({secret: 'shhhhhhared-secret'});

// authorization check
function authorizationCheck(req, res, next) {
  if (!req.user.admin) { 
   return res.sendStatus(401);
  } else {
    // move to the next middleware, cause it's ok
    next();
  } 
}

// the real route handler
function myRouteHandler(req, res){
  doSomeWork(function(err, data){
    if (err) { return next(err); }
    res.json(data);
  });
}

// put it all together
router.use("/protected", processjwt, authorizationCheck);
router.get("/protected", myRouteHandler);

there are dozens of variations on this setup that can be used, but this gets the idea across.

like image 111
Derick Bailey Avatar answered Oct 20 '22 18:10

Derick Bailey