• Mail us
  • Book a Meeting
  • Call us
  • Chat with us

NodeJS

Protect Your Routes with Guards in Nest.js for Enhanced Security


Introduction

In any back-end application, security of routes plays an essential part in providing permission to authorized users to access resources. Nest.js, which is a progressive Node.js framework, offers Guards as a standard module for processing authentication and authorization.

What Are Guards in Nest.js?

The security system of Nest.js utilizes specific implementation methods that work as middleware pieces. Guards indicate which requests should proceed through particular condition-based examinations. Guards at the route level function before the route handler to perform their operations.

The main use of guards occurs during authentication processes to determine if users have already logged in so they can access protected routes.

How to Implement Guards in Nest.js

Let’s go step by step to implement a basic authentication guard in a Nest.js application.

1. Create a Custom Guard

Nest.js provides an interface called CanActivate, which must be implemented when creating a guard.

import { CanActivate, ExecutionContext, Injectable, UnauthorizedException } from '@nestjs/common';import { Request } from 'express';import { JwtService } from '@nestjs/jwt';@Injectable()export class AuthGuard implements CanActivate { constructor(private jwtService: JwtService) {}  canActivate(context: ExecutionContext): boolean {   const request: Request = context.switchToHttp().getRequest();   const authHeader = request.headers.authorization;    if (!authHeader || !authHeader.startsWith('Bearer ')) {     throw new UnauthorizedException('Missing or invalid token');   }    const token = authHeader.split(' ')[1];   try {     const decoded = this.jwtService.verify(token);     request.user = decoded; // Attaching the decoded user data to the request object     return true;   } catch (error) {     throw new UnauthorizedException('Invalid token');   } }}

Apply the Guard to Routes

Guards can be applied at different levels:

At the Controller Level

Applying a guard to an entire controller ensures all routes inside it are protected.

import { Controller, Get, UseGuards } from '@nestjs/common';@Controller('protected')@UseGuards(AuthGuard)export class ProtectedController { @Get() getData() {   return { message: 'This is a protected route' }; }}

 

At the Route Level

If you want to protect only specific routes, apply the guard to the method:

import { Controller, Get, UseGuards } from '@nestjs/common';@Controller('users')export class UsersController { @Get('profile') @UseGuards(AuthGuard) getProfile() {   return { message: 'User profile data' }; }} 

Using Guards Globally

If you need to apply an authentication guard across all routes in your application, you can register it globally in the main AppModule:

import { Module } from '@nestjs/common';import { APP_GUARD } from '@nestjs/core';@Module({ providers: [   {     provide: APP_GUARD,     useClass: AuthGuard,   }, ],})export class AppModule {}

 

This ensures that every request is checked before reaching any controller.

Role-Based Access Control (RBAC) with Guards

Beyond authentication, guards can be used for role-based authorization, ensuring only users with specific roles can access certain resources.

Let’s create a RolesGuard to allow only users with a specific role (e.g., admin):

import { CanActivate, ExecutionContext, Injectable, ForbiddenException } from '@nestjs/common';@Injectable()export class RolesGuard implements CanActivate { constructor(private allowedRoles: string[]) {} canActivate(context: ExecutionContext): boolean {   const request = context.switchToHttp().getRequest();   const user = request.user; // Assuming the AuthGuard has set the user object   if (!user || !this.allowedRoles.includes(user.role)) {     throw new ForbiddenException('You do not have permission to access this resource');   }   return true; }} 

To use this guard dynamically, create a decorator:

import { SetMetadata } from '@nestjs/common';export const Roles = (...roles: string[]) => SetMetadata('roles', roles);

 

Apply it to specific routes:

import { Controller, Get, UseGuards } from '@nestjs/common';import { RolesGuard } from './roles.guard';import { Roles } from './roles.decorator';@Controller('admin')export class AdminController { @Get() @UseGuards(new RolesGuard(['admin'])) // Only admins can access this route getAdminData() {   return { message: 'Admin panel data' }; }}

Key Takeaways

  • Nest.js Guards provide a powerful way to secure routes by handling authentication and authorization before requests reach the controller.

  • Custom Guards can be implemented using the CanActivate interface to verify user credentials.

  • Flexible Usage allows guards to be applied at the route, controller, or global level based on security needs.

  • Role-Based Access Control (RBAC) can be enforced using guards to restrict access based on user roles.

  • Global Guards can be set up to ensure that every request is authenticated without manually applying guards to each route.

This approach helps maintain a secure, modular, and scalable Nest.js application.

 

Ready to transform your business with our technology solutions?   Contact us today to Leverage Our Nodejs Expertise. 

Share

facebook
LinkedIn
Twitter
Mail
NodeJS

Related Center Of Excellence