Guard

  • A guard is a class annotated with the @Injectable() decorator, which implements the CanActivate interface.

alt text

  • Guards are executed after all middleware, but before any interceptor or pipe.

Auth Guards

  • auth.guard.ts
    import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';

@Injectable()
export class AuthGuard implements CanActivate {

canActivate( context: ExecutionContext,): boolean | Promise<boolean> | Observable<boolean> {

const request = context.switchToHttp().getRequest();
return validateRequest(request);

}

}

Role based Authentication

  • roles.guard.ts
    import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';

@Injectable()
export class RolesGuard implements CanActivate {

canActivate( context: ExecutionContext,): boolean | Promise<boolean> | Observable<boolean> {

return true;

}
}

Binding Guards

  • Like pipes and exception filters, guards can be controller-scoped, method-scoped, or global-scoped.

@Controller('cats')
@UseGuards(RolesGuard)
export class CatsController {}

Global guard

    app.useGlobalGuards(new RolesGuard());

Example

    @Post()
@Roles(['admin'])
async create(@Body() createCatDto: CreateCatDto) {

this.catsService.create(createCatDto);

}

RolesGuard

  • RolesDecorator
    import { Reflector } from '@nestjs/core';

export const Roles = Reflector.createDecorator<string[]>();
    import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { Roles } from './roles.decorator';

@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 matchRoles(roles, user.roles);

}
}