Implementing Role-Based Access Control (RBAC) in NestJS is a crucial step toward enhancing the security of your application. RBAC allows you to define permissions based on user roles, ensuring that users can only access resources and perform actions they are authorized for. This article guides you through the process of integrating RBAC into a NestJS project.

Understanding RBAC in NestJS

RBAC is a security model that restricts system access to authorized users based on their roles. In NestJS, implementing RBAC involves creating roles, assigning permissions, and securing routes with guards. This approach simplifies permission management and improves application security.

Setting Up Roles and Permissions

Start by defining roles and associated permissions. For example, roles like Admin, Editor, and Viewer can have different levels of access.

  • Admin: Full access to all resources.
  • Editor: Can modify content but not manage users.
  • Viewer: Read-only access.

Creating Role and Permission Decorators

Use custom decorators to assign roles to route handlers. This makes it easy to specify who can access each endpoint.

import { SetMetadata } from '@nestjs/common';

export const Roles = (...roles: string[]) => SetMetadata('roles', roles);

Implementing the Roles Guard

The guard checks if the user has the required role to access a route. It reads the roles from route metadata and compares them with the user's roles.

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    const roles = this.reflector.get('roles', context.getHandler());
    if (!roles) {
      return true;
    }
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    return user?.roles.some(role => roles.includes(role));
  }
}

Integrating RBAC into Your Application

Apply the Roles decorator and RolesGuard to protect routes.

import { Controller, Get, UseGuards } from '@nestjs/common';
import { Roles } from './roles.decorator';
import { RolesGuard } from './roles.guard';

@Controller('admin')
@UseGuards(RolesGuard)
export class AdminController {
  @Get()
  @Roles('Admin')
  getAdminData() {
    return { message: 'This is admin data' };
  }
}

Assigning Roles to Users

Ensure your authentication system includes user roles. When users authenticate, attach their roles to the user object, which the guard will verify during route access.

Conclusion

Implementing RBAC in NestJS enhances application security by controlling access based on user roles. By defining roles, creating decorators, and using guards, you can manage permissions efficiently and securely. This approach not only protects sensitive data but also simplifies permission management across your application.