0
0
NestJSframework~5 mins

Role-based authorization in NestJS

Choose your learning style9 modes available
Introduction

Role-based authorization helps control who can do what in your app. It keeps things safe by letting only certain users access specific parts.

When you want to allow only admins to delete data.
When you want regular users to view content but not edit it.
When different user roles have different access levels in your app.
When you want to protect sensitive routes based on user roles.
Syntax
NestJS
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 requiredRoles = this.reflector.getAllAndOverride<string[]>('roles', [
      context.getHandler(),
      context.getClass(),
    ]);
    if (!requiredRoles) {
      return true;
    }
    const { user } = context.switchToHttp().getRequest();
    return requiredRoles.some(role => user.roles?.includes(role));
  }
}

The RolesGuard checks if the user has the needed roles to access a route.

Use @SetMetadata('roles', ['roleName']) on controllers or routes to specify roles.

Examples
This helper decorator sets roles metadata on routes or controllers.
NestJS
import { SetMetadata } from '@nestjs/common';

export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
This route can only be accessed by users with the 'admin' role.
NestJS
@Roles('admin')
@Get('admin-data')
getAdminData() {
  return 'Secret admin data';
}
The guard protects the controller, and the route allows users with 'user' or 'admin' roles.
NestJS
@UseGuards(RolesGuard)
@Controller('users')
export class UsersController {
  @Roles('user', 'admin')
  @Get('profile')
  getProfile() {
    return 'User profile data';
  }
}
Sample Program

This example shows a controller with two routes. One route is only for admins, the other for users or admins. The RolesGuard checks the user's roles before allowing access.

NestJS
import { Controller, Get, UseGuards } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { Injectable, CanActivate, ExecutionContext, SetMetadata } from '@nestjs/common';

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

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

  canActivate(context: ExecutionContext): boolean {
    const requiredRoles = this.reflector.getAllAndOverride<string[]>('roles', [
      context.getHandler(),
      context.getClass(),
    ]);
    if (!requiredRoles) {
      return true;
    }
    const { user } = context.switchToHttp().getRequest();
    return requiredRoles.some(role => user.roles?.includes(role));
  }
}

@UseGuards(RolesGuard)
@Controller('dashboard')
export class DashboardController {
  @Roles('admin')
  @Get('admin')
  getAdminDashboard() {
    return 'Welcome to the admin dashboard';
  }

  @Roles('user', 'admin')
  @Get('user')
  getUserDashboard() {
    return 'Welcome to the user dashboard';
  }
}
OutputSuccess
Important Notes

Make sure your authentication system adds a user object with roles to the request.

Roles are usually strings like 'admin', 'user', or 'editor'.

Use @UseGuards(RolesGuard) to activate role checks on controllers or routes.

Summary

Role-based authorization controls access by user roles.

Use decorators to mark which roles can access routes.

Use a guard to check roles before allowing access.