Volver a la página principal
domingo 7 julio 2024
4

Cómo Utilizar NestJS y JWT para Autenticación

Introducción

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.

Prerrequisitos

Antes de comenzar, asegúrate de tener instalado:

  • Node.js
  • npm (Node Package Manager)
  • Nest CLI

Paso 1: Crear una Nueva Aplicación NestJS

Primero, crea una nueva aplicación NestJS utilizando el CLI de Nest:

nest new nest-jwt-auth
cd nest-jwt-auth

Paso 2: Instalar Dependencias Necesarias

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

Paso 3: Configurar Módulo de Autenticación

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

Paso 4: Configurar Estrategia JWT

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 };
  }
}

Paso 5: Configurar Servicio de Autenticación

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),
    };
  }
}

Paso 6: Configurar Controlador de Autenticación

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);
  }
}

Paso 7: Proteger Rutas con JWT

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);
  }
}

Paso 8: Configurar el Módulo Principal

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 {}

Conclusión

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.

Compartir:
Creado por:
Author photo

Jorge García

Fullstack developer