How to use guards and implement authentication
Let's understand NestJS guard function and implement authentication.
On this page
overview
NestJS has a feature called a guard to decide whether to continue processing the request. Guards are available by implementing the CanActivate
interface, and are most commonly used to handle authentication.
Guards have two main roles:
- Authentication: User privileges, roles, and ACLs are verified to determine whether to continue processing the request.
- Request Control: Works between middleware and interceptors to control request processing.
This article explains how to use NestJS guards and how to implement authentication using guards.
Creating and using guards
You can create guards using NestJS’s CLI tools. Running the following command will create a guard named AuthGuard
.
nest g guard users/guard/auth
The created guard implements the CanActivate
interface and has a canActivate
method. This method is for deciding whether to continue processing the request.
Below is an example guard that rejects the request if the query parameter is not present.
/src/users/guard/auth/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 !!request.query.params;
}
}
In the code above, the canActivate
method checks the query parameters of the request and only continues processing the request if the params
parameter is present.
To use the created guards, bind them to your controllers or route handlers using the @UseGuards
decorator. An example is shown below.
import {
Controller,
Get,
Post,
Put,
Delete,
Body,
Param,
HttpException,
HttpStatus,
Use filters,
Parse Int Pipe,
Use Guards,
} from '@nestjs/common';
import { UsersService } from './users.service';
import { ForbiddenException } from './exceptions/forbidden.exception';
import { HttpExceptionFilter } from './filters/http-exception/http-exception.filter';
import { AuthGuard } from './guard/auth/auth.guard';
@Controller('users')
@UseFilters(new HttpExceptionFilter())
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Get()
getUsers(): User[] {
return this.usersService.getUsers();
}
@Post()
addUser(@Body() name: string): void {
this.usersService.addUser(name);
}
@Put(':id')
putUser(
@Param('id', ParseIntPipe) id: number,
@Body('name') name: string,
): void {
this.usersService.putUser(id, name);
}
@Delete(':id')
deleteUser(@Param('id', ParseIntPipe) id: number): void {
this.usersService.deleteUser(id);
}
@Get('throw')
getException(): string {
throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
}
@Get('custom_throw')
getCustomException(): string {
throw new ForbiddenException();
}
@Get('guard')
@UseGuards(AuthGuard)
getGuard(): string {
return 'Guard is working';
}
}
The above code uses the @UseGuards
decorator to bind AuthGuard
to the getHello
route handler. With this, when there is a request to getHello
, the canActivate
method of AuthGuard
will be executed first, and the request processing will continue based on the result.
test
## If there is no parameter, it will not pass.
curl http://localhost:3000/users/guard
## Passes if there are parameters.
curl http://localhost:3000/users/guard?params=true
summary
Guards in NestJS are powerful features that determine whether or not to continue processing a request. In particular, when performing user authentication and authority verification, the use of guards enables efficient processing. Understand how to use guards and use them appropriately.