Creating Permissions and Validations Middleware

Taylor Emma
3 Min Read
Disclosure: This website may contain affiliate links, which means I may earn a commission if you click on the link and make a purchase. I only recommend products or services that I personally use and believe will add value to my readers. Your support is appreciated!

The first thing we should define is who can use the usersresource. These are the scenarios that we’ll need to handle:

·         Public for creating users (registration process). We will not use JWT for this scenario.

·         Private for the logged-in user and for admins to update that user.

·         Private for admin only for removing user accounts.

Having identified these scenarios, we will first require a middleware that always validates the user if they are using a valid JWT. The middleware in /common/middlewares/auth.validation.middleware.js can be as simple as:

exports.validJWTNeeded = (req, res, next) => {
    if (req.headers['authorization']) {
        try {
            let authorization = req.headers['authorization'].split(' ');
            if (authorization[0] !== 'Bearer') {
                return res.status(401).send();
            } else {
                req.jwt = jwt.verify(authorization[1], secret);
                return next();
            }
        } catch (err) {
            return res.status(403).send();
        }
    } else {
        return res.status(401).send();
    }
}; 

We will use HTTP error codes for handling request errors:

·         HTTP 401 for an invalid request

·         HTTP 403 for a valid request with an invalid token, or valid token with invalid permissions

We can use the bitwise AND operator (bitmasking) to control the permissions. If we set each required permission as a power of 2, we can treat each bit of the 32bit integer as a single permission. An admin can then have all permissions by setting their permission value to 2147483647. That user could then have access to any route. As another example, a user whose permission value was set to 7 would have permissions to the roles marked with bits for values 1, 2, and 4 (two to the power of 0, 1, and 2).

The middleware for that would look like this:

exports.minimumPermissionLevelRequired = (required_permission_level) => {
   return (req, res, next) => {
       let user_permission_level = parseInt(req.jwt.permission_level);
       let user_id = req.jwt.user_id;
       if (user_permission_level & required_permission_level) {
           return next();
       } else {
           return res.status(403).send();
       }
   };
};

The middleware is generic. If the user permission level and the required permission level coincide in at least one bit, the result will be greater than zero and we can let the action proceed, otherwise the HTTP code 403 will be returned.

Now, we need to add the authentication middleware to the user’s module routes in /users/routes.config.js:

app.post('/users', [
   UsersController.insert
]);
app.get('/users', [
   ValidationMiddleware.validJWTNeeded,
   PermissionMiddleware.minimumPermissionLevelRequired(PAID),
   UsersController.list
]);
app.get('/users/:userId', [
   ValidationMiddleware.validJWTNeeded,
   PermissionMiddleware.minimumPermissionLevelRequired(FREE),
   PermissionMiddleware.onlySameUserOrAdminCanDoThisAction,
   UsersController.getById
]);
app.patch('/users/:userId', [
   ValidationMiddleware.validJWTNeeded,
   PermissionMiddleware.minimumPermissionLevelRequired(FREE),
   PermissionMiddleware.onlySameUserOrAdminCanDoThisAction,
   UsersController.patchById
]);
app.delete('/users/:userId', [
   ValidationMiddleware.validJWTNeeded,
   PermissionMiddleware.minimumPermissionLevelRequired(ADMIN),
   UsersController.removeById
]);

This concludes the basic development on our REST API. All that remains to be done is to test it all out.

Share This Article
A senior editor for The Mars that left the company to join the team of SenseCentral as a news editor and content creator. An artist by nature who enjoys video games, guitars, action figures, cooking, painting, drawing and good music.
Leave a review