NestJS es un framework de Node.js que permite construir aplicaciones backend eficientes, escalables y mantenibles utilizando TypeScript. Una de las características fundamentales para muchas aplicaciones es la autenticación y autorización de usuarios. Para ello, JSON Web Tokens (JWT) es una herramienta popular que permite transmitir información de forma segura entre un cliente y un servidor. En este artículo, aprenderás cómo integrar JWT con NestJS para manejar la autenticación de usuarios.
Antes de comenzar, asegúrate de tener instalado:
Primero, crea una nueva aplicación NestJS utilizando el CLI de Nest:
nest new nest-jwt-auth
cd nest-jwt-auth
Instala las siguientes dependencias necesarias para trabajar con JWT:
npm install @nestjs/jwt @nestjs/passport passport passport-jwt bcryptjs
npm install --save-dev @types/passport-jwt @types/bcryptjs
Crea un nuevo módulo de autenticación utilizando el CLI de Nest:
nest generate module auth
A continuación, crea un servicio y un controlador dentro del módulo de autenticación:
nest generate service auth
nest generate controller auth
Configura la estrategia JWT en el servicio de autenticación. Primero, crea un archivo jwt.strategy.ts
en la carpeta auth
:
// src/auth/jwt.strategy.ts
import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { ConfigService } from '@nestjs/config';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(private configService: ConfigService) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: configService.get<string>('JWT_SECRET'),
});
}
async validate(payload: any) {
return { userId: payload.sub, username: payload.username };
}
}
Añade la lógica para generar y validar tokens JWT en el servicio de autenticación:
// src/auth/auth.service.ts
import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { UsersService } from '../users/users.service';
import * as bcrypt from 'bcryptjs';
@Injectable()
export class AuthService {
constructor(
private usersService: UsersService,
private jwtService: JwtService
) {}
async validateUser(username: string, pass: string): Promise<any> {
const user = await this.usersService.findOne(username);
if (user && await bcrypt.compare(pass, user.password)) {
const { password, ...result } = user;
return result;
}
return null;
}
async login(user: any) {
const payload = { username: user.username, sub: user.userId };
return {
access_token: this.jwtService.sign(payload),
};
}
}
Configura el controlador de autenticación para manejar las solicitudes de login y proteger las rutas:
// src/auth/auth.controller.ts
import { Controller, Post, UseGuards, Request } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalAuthGuard } from './local-auth.guard';
@Controller('auth')
export class AuthController {
constructor(private authService: AuthService) {}
@UseGuards(LocalAuthGuard)
@Post('login')
async login(@Request() req) {
return this.authService.login(req.user);
}
}
Utiliza el guard de JWT para proteger las rutas en otros módulos. Por ejemplo, en un módulo de usuarios:
// src/users/users.controller.ts
import { Controller, Get, UseGuards } from '@nestjs/common';
import { UsersService } from './users.service';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
@Controller('users')
export class UsersController {
constructor(private usersService: UsersService) {}
@UseGuards(JwtAuthGuard)
@Get('profile')
getProfile(@Request() req) {
return this.usersService.findOne(req.user.username);
}
}
Asegúrate de importar y configurar los módulos en app.module.ts
:
// src/app.module.ts
import { Module } from '@nestjs/common';
import { AuthModule } from './auth/auth.module';
import { UsersModule } from './users/users.module';
import { ConfigModule } from '@nestjs/config';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
}),
AuthModule,
UsersModule,
],
})
export class AppModule {}
Has configurado con éxito la autenticación basada en JWT en una aplicación NestJS. Esta configuración permite a los usuarios autenticarse y proteger rutas específicas en tu aplicación, asegurando que solo los usuarios autorizados puedan acceder a ciertas funcionalidades. NestJS, con su modularidad y soporte para TypeScript, junto con JWT, ofrece una manera segura y eficiente de manejar la autenticación en aplicaciones modernas.
Jorge García
Fullstack developer