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?
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.
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:
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.
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" ] }
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With