How to Create Role based Authorization Middleware with Casbin and Nest.js
Tags: rbac, casbin, nest, security
Published: 2019-05-11 13:53:21

---
title: How to Create Role based Authorization Middleware with Casbin and Nest.js
published: true
description: Casbin is an authorization library that supports access control models like ACL, RBAC, ABAC
tags: rbac, casbin, nest, security
---

*Read on [my site](https://antaraksi.com/casbin-midleware-for-nest-js-with-restful-policy/)*.

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:
{% youtube mWlPNrCgVdE %}

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](https://github.com/x1yy/theproject).