Nest
Tutorial Nest: Estrategia de autenticación JWT
Nest JWT: autenticación y uso. Domina la autenticación utilizando JWT en Nest con ejemplos prácticos y detallados.
Aprende Nest GRATIS y certifícateJWT (JSON Web Token) es un estándar abierto (RFC 7519) para la creación de tokens de acceso que permiten la autenticación y autorización seguras entre dos partes, como un cliente y un servidor.
JWT se utiliza comúnmente para transmitir información de identidad y privilegios en aplicaciones web, APIs y servicios.
JWT es un método compacto y seguro para transmitir información entre dos partes como un objeto JSON, que se firma digitalmente y, opcionalmente, se cifra. La firma digital garantiza que el emisor del token (generalmente, un servidor de autenticación) pueda verificar la integridad de los datos y asegurarse de que no se hayan modificado durante la transmisión.
NestJS ofrece soporte para implementar autenticación JWT a través de su paquete @nestjs/jwt
y el módulo Passport
.
Estructura JWT
La estructura de un token JWT consta de tres partes, separadas por puntos (.
):
1. Encabezado (Header): El encabezado es un objeto JSON que contiene información sobre el tipo de token (generalmente JWT) y el algoritmo de firma utilizado (como HS256 o RS256).
El encabezado se codifica en base64 y se utiliza para verificar la firma del token.
Ejemplo de encabezado:
{
"alg": "HS256",
"typ": "JWT"
}
2. Carga útil (Payload): La carga útil es un objeto JSON que contiene los llamados "claims" (reclamaciones), que son declaraciones sobre el sujeto (usuario) y otros metadatos.
Los claims pueden ser de tres tipos: claims registrados, públicos y privados.
Los claims registrados son un conjunto de claims predefinidos por el estándar JWT, como "iss" (emisor), "exp" (tiempo de expiración) y "sub" (sujeto).
Los claims públicos y privados son específicos de la aplicación y pueden contener información como roles de usuario, permisos, etc.
Al igual que el encabezado, la carga útil se codifica en base64.
Ejemplo de carga útil:
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022,
"exp": 1516242622,
"role": "admin"
}
3. Firma (Signature): La firma se crea utilizando el encabezado codificado en base64, la carga útil codificada en base64 y una clave secreta o un par de claves pública/privada, dependiendo del algoritmo de firma utilizado.
La firma es esencial para verificar la integridad y autenticidad del token JWT.
Ejemplo de cómo calcular la firma (usando el algoritmo HS256 y una clave secreta):
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret_key
)
Cuando se combinan, estas tres partes forman el token JWT completo, que se ve así:
[header_base64].[payload_base64].[signature]
Cómo funciona JWT
Aquí hay un ejemplo de flujo de autenticación y autorización utilizando JWT:
- El cliente envía sus credenciales (nombre de usuario y contraseña) al servidor de autenticación en una solicitud de inicio de sesión.
- El servidor de autenticación verifica las credenciales y, si son válidas, crea un token JWT que contiene información sobre el usuario (claims) y firma el token con una clave secreta o un par de claves pública/privada.
- El servidor devuelve el token JWT al cliente.
- El cliente almacena el token JWT y lo incluye en el encabezado Authorization de las solicitudes posteriores al servidor, generalmente como un "Bearer Token".
- El servidor verifica la firma del token JWT en cada solicitud y comprueba si el token ha expirado. Si el token es válido, el servidor procesa la solicitud según los privilegios del usuario representados por el token. Si el token no es válido o ha expirado, el servidor deniega el acceso y puede solicitar al cliente que vuelva a autenticarse.
Es importante tener en cuenta que, aunque JWT proporciona un mecanismo seguro para transmitir información entre dos partes, los tokens deben tratarse como datos sensibles y protegerse adecuadamente.
No se debe almacenar información confidencial en la carga útil del token, ya que los datos codificados en base64 pueden decodificarse fácilmente.
JWT en NestJS
A continuación, se detalla el proceso para implementar una estrategia JWT en una aplicación NestJS.
Instalación de paquetes
Primero, es necesario instalar los siguientes paquetes:
npm install @nestjs/jwt @nestjs/passport passport passport-jwt
Configuración del módulo JWT
Crea un módulo de autenticación
Una vez que los paquetes estén instalados, se debe configurar el módulo JWT. Para esto, se crea un módulo AuthModule
con un servicio y un controlador para manejar la autenticación:
nest generate module auth
nest generate service auth
nest generate controller auth
Configura el módulo JWT
// auth.module.ts
import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { UserModule } from '../user/user.module';
@Module({
imports: [
UserModule,
PassportModule,
JwtModule.register({
secret: 'claveSecreta',
signOptions: { expiresIn: '1h'}
})
],
providers: [AuthService],
controllers: [AuthController]
})
export class AuthModule {}
En AuthModule
, se importa UserModule
, PassportModule
y JwtModule
. En las importaciones se configura JwtModule
con la clave secreta y la duración de la sesión (1 hora en este ejemplo).
En el apartado de secret
, se debe utilizar una clave secreta segura y no debe incluirse el código en un entorno de producción. En su lugar, se puede almacenar en una variable de entorno.
Creación de la estrategia JWT
Luego, dentro de la carpeta auth, se crea una estrategia para manejar la autenticación JWT:
// jwt.strategy.ts
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { UsersService } from "src/users/users.service";
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(private userService: UsersService) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: process.env.JWT_SECRET,
});
}
async validate(payload: any) {
let user = await this.userService.findById(payload.sub);
if(!user)
throw new UnauthorizedException('Autenticación incorrecta');
let {password, ...userInfo} = user;
return userInfo;
}
}
En esta estrategia:
**PassportStrategy(Strategy)**
: Define cómo se extrae el JWT del encabezado de autorización y cómo se valida.
**jwtFromRequest**
: Especifica cómo se extraerá el JWT de la solicitud entrante.
**ignoreExpiration**
: Indica si se debe ignorar la fecha de expiración del token.
**secretOrKey**
: Es el secreto o clave que se usará para descifrar el token.
**validate**
: Se invoca después de que el token ha sido validado y decodificado. Aquí es donde se puede hacer verificaciones adicionales, como comprobar la existencia de un usuario.
Registrar la estrategia
Después de crear la estrategia, se debe registrar en el módulo para que pueda ser inyectada:
// auth.module.ts
@Module({
providers: [ AuthService, JwtStrategy ], // Se agrega JwtStrategy
})
export class AuthModule {}
Implementación de autenticación y protección de rutas
Para proteger rutas específicas, se utiliza el decorador @UseGuards()
.
Primero, dentro de la carpeta auth, se debe crear un AuthGuard
para JWT:
// jwt-auth.guard.ts
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}
Y luego, se puede usar este guardián para proteger las rutas:
// app.controller.ts
import { Controller, UseGuards, Get } from '@nestjs/common';
import { JwtAuthGuard } from './jwt-auth.guard';
@Controller()
export class AppController {
@UseGuards(JwtAuthGuard)
@Get('ruta-protegida')
rutaProtegida() {
return 'Esta ruta está protegida con JWT';
}
}
De esta forma, cuando se acceda a ruta-protegida
, NestJS requerirá un JWT válido en el encabezado de autorización para permitir el acceso.
Generación y validación del token
Para completar el proceso de autenticación JWT, también es necesario proporcionar un mecanismo para generar el token JWT y validarlo.
Servicio de autenticación
Se puede crear un servicio que maneje la generación y validación de tokens.
// auth.service.ts
import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
@Injectable()
export class AuthService {
constructor(private readonly jwtService: JwtService) {}
async login(user: any) {
const payload = { username: user.username, sub: user.userId };
return {
access_token: this.jwtService.sign(payload),
};
}
// ... cualquier otro método relacionado con la autenticación
}
En el servicio anterior, se tiene un método login
que genera un token JWT cuando un usuario inicia sesión en una aplicación.
Se crea un objeto payload
que contiene la información que se incluirá en el token JWT. En este caso, el payload incluye el username y un identificador único (userId) del usuario que está iniciando sesión.
El método sign
del JwtService
se utiliza para firmar el payload y generar un token JWT. El token se devuelve en un objeto que tiene una clave access_token
.
Endpoint de autenticación
Luego, se puede crear un endpoint que maneje el inicio de sesión de los usuarios y devuelva el token JWT.
// auth.controller.ts
import { Controller, Post, Request, Body } from '@nestjs/common';
import { AuthService } from './auth.service';
@Controller('auth')
export class AuthController {
constructor(private readonly authService: AuthService) {}
@Post('login')
async login(@Body() userDto: any) {
return this.authService.login(userDto);
}
}
El cliente ahora puede enviar una solicitud POST a /auth/login
con las credenciales del usuario. Si las credenciales son correctas, el servidor devolverá un token JWT que el cliente deberá incluir en las solicitudes siguientes para acceder a rutas protegidas.
Conclusión
La estrategia de autenticación JWT en NestJS permite una gestión eficiente y segura de las sesiones de los usuarios. La combinación de JWT con NestJS proporciona una estructura modular y escalable para crear aplicaciones con autenticación robusta.
Ejercicios de esta lección Estrategia de autenticación JWT
Evalúa tus conocimientos de esta lección Estrategia de autenticación JWT con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.
Métodos GET en controladores
Método find en un servicio con repositorio
Desarrollo e inyección de servicios
Creación de entidades y tablas
Método DELETE en un controlador
Filtrados en consultas de repositorios
Método GET en un controlador
Estrategia de autenticación JwtStrategy
CRUD con repositorios
Método delete en un servicio con repositorio
API REST CRUD de entidad Restaurante con TypeORM
Creación de una entidad TypeORM
Crear y utilizar módulos
Métodos PUT en controladores
Iniciar sesión método de login
Configuración de TypeORM con MySQL
Gestión de errores en controladores
Decoradores en entidades
Instalación NestJS
Recibir y servir imágenes
Estrategia de autenticación JWT
Método PUT en un controlador
Comandos NestJS CLI
Método POST en un controlador
Login y registro
API REST CRUD de entidades Product y Manufacturer
Método save en un servicio con repositorio
Registro de usuarios
Métodos POST en controladores
Todas las lecciones de Nest
Accede a todas las lecciones de Nest y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.
Instalación Nestjs
Introducción Y Entorno
Comandos Nestjs Cli
Introducción Y Entorno
Métodos Get En Controladores
Controladores
Métodos Post En Controladores
Controladores
Métodos Put En Controladores
Controladores
Métodos Delete En Controladores
Controladores
Gestión De Errores En Controladores
Controladores
Recibir Y Servir Imágenes
Controladores
Desarrollo E Inyección De Servicios
Servicios E Inyección De Dependencias
Crear Y Utilizar Módulos
Módulos
Configuración De Typeorm Con Mysql
Typeorm
Creación De Entidades Y Tablas
Typeorm
Decoradores En Entidades
Typeorm
Crud Con Repositorios
Typeorm
Filtrados En Consultas De Repositorios
Typeorm
Registro De Usuarios
Autenticación
Iniciar Sesión Método De Login
Autenticación
Estrategia De Autenticación Jwtstrategy
Autenticación
Login Y Registro
Autenticación
Estrategia De Autenticación Jwt
Autenticación
Certificados de superación de Nest
Supera todos los ejercicios de programación del curso de Nest y obtén certificados de superación para mejorar tu currículum y tu empleabilidad.
En esta lección
Objetivos de aprendizaje de esta lección
- Comprender el propósito y la importancia de JWT.
- Conocer la estructura de un token JWT.
- Implementar una estrategia de autenticación JWT en NestJS.
- Proteger rutas específicas con JWT.
- Generar y validar tokens JWT.