DEV Community

Dwi purnomo
Dwi purnomo

Posted on • Edited on

12 2

How to Create Role based Authorization Middleware with Casbin and Nest.js

Read on my site.

In this article, i will show you how to create Role based authorization middleware with Casbin and Nest.js. Casbin is an authorization library that supports access control models like ACL, RBAC, ABAC for Golang, Java, PHP and Node.js, but in this article, we will use the Node.js.

Nest is a progressive Node.js framework for building efficient, reliable and scalable server-side applications. It uses Typescript language and support multiple core server like Express, Koa or Fastify.

If you prefer to watch in video format:

Here is the text format:

Before we create the project, install Nest first.

npm i -g @nestjs/cli

And then we create a project with the Nest cli

nest new theproject

Then, open the project directory and install the Casbin

cd theproject
npm install --save casbin

After this, we enter the coding phase.

First, create the policy configuration for Casbin.

In the src, create a directory named casbin_conf.

cd src
mkdir casbin_conf

Create model.conf and policy.csv in the casbin_conf

File model.conf:

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = r.sub == p.sub && keyMatch(r.obj, p.obj) && (r.act == p.act || p.act == "*")

File policy.csv:

p, admin, /*, GET
p, notadmin, /, POST

In the policy we define two rules, one is for user who have admin role and the other is for user who have notadmin role.

After that, we create the Nest middleware.

Create a middleware named authorization.middleware.ts in src

File authorization.middleware.ts:

import { Enforcer } from 'casbin';

export class BasicAuthorizer {
    private req: any;
    private enforcer: any;

    constructor(req, enforcer) {
        this.req = req;
        this.enforcer = enforcer;
    }

    getUserRole() {
        const { user } = this.req;
        const { role } = user;
        return role;
    }

    checkPermission() {
        const { req, enforcer } = this;
        const { originalUrl: path, method } = req;
        const userRole = this.getUserRole();
        return enforcer.enforce(userRole, path, method);
    }
}

// the authorizer middleware
export function authz(newEnforcer: () => Promise<Enforcer>) {
    return async (req, res, next) => {
        const enforcer = await newEnforcer();

        // user sample
        req.user = {role: 'admin'};

        if(!(enforcer instanceof Enforcer)) {
            res.status(500).json({500: 'Invalid enforcer'});
            return;
        }

        const authorizer = new BasicAuthorizer(req, enforcer);
        if(!authorizer.checkPermission()) {
            res.status(403).json({403: 'Forbidden'});
            return;
        }

        next();
    }
};

That's the authorization middleware logic, Casbin will help checking the permission.

Then we integrate the middleware in Nest project bootstrap.

Find the maint.ts, integrate the authorization middleware in the app:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

import { newEnforcer } from 'casbin';
import { authz } from './authorization.middleware';

import { join } from 'path';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // authorization middleware that is registered as global middleware
  app.use(authz(async() => {
      const enforcer = await newEnforcer(join(__dirname, 'casbin_conf/model.conf'), join(__dirname, 'casbin_conf/policy.csv'));
      return enforcer;
  }));
  await app.listen(3000);
}
bootstrap();

That is the authorization middleware that is registered as global middleware in the app.

Boot up the project to test:

npm run start:dev

If you want to experiment, modify the sample user in the authz, remove that if you want make it into production.

Here is the project repository.

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay