La autenticación es un componente esencial en la mayoría de las aplicaciones modernas, y JWT (JSON Web Tokens) es un método comúnmente utilizado para manejarla. En este contexto, usaremos Passport, un popular middleware de autenticación para Node.js, y NestJS proporciona una integración sencilla para Passport.
NPM:
npm install --save @nestjs/jwt @nestjs/passport passport passport-jwt
Yarn:
yarn add @nestjs/jwt @nestjs/passport passport passport-jwt
Estos paquetes incluyen:
@nestjs/jwt
: Provee la funcionalidad JWT para NestJS.@nestjs/passport
: Integra Passport dentro del ecosistema de NestJS.passport
: Es el paquete principal de Passport, un middleware de autenticación muy popular para Node.js.passport-jwt
: Es una estrategia Passport para autenticar con un JSON Web Token.
Recuerda siempre instalar y guardar estos paquetes en tu package.json
, para que sean instalados automáticamente al ejecutar npm install
o yarn install
en un nuevo entorno.
La estructura del módulo de autenticación se dividen en varias partes:
-
Módulo de Autenticación:
En NestJS, se utiliza el decorador
@Module()
para marcar una clase como un módulo. Dentro del módulo de autenticación, importas los módulos y estrategias que necesitas para la autenticación.Aquí, el módulo de autenticación registra la estrategia predeterminada como 'jwt' y también registra el módulo JWT con una clave secreta y opciones de firma.
-
Estrategia JWT:
Aquí se define la estrategia para manejar el JWT. Extiendes
PassportStrategy(Strategy)
para utilizar la estrategia proporcionada por passport-jwt. En el constructor, defines las opciones para extraer el JWT del encabezado de autorización y el secretOrKey que es necesario para verificar la firma del token.El método
validate()
se llama automáticamente cuando un usuario intenta autenticarse utilizando un JWT. El payload del JWT se pasa a este método, y puedes definir tu propia lógica de validación aquí. -
Controlador de Autenticación:
Este es el lugar donde expones tus endpoints de autenticación. El decorador
@UseGuards()
se utiliza para proteger las rutas, y puedes especificar la estrategia que deseas usar para proteger la ruta. Aquí, la estrategia jwt se utiliza para proteger la ruta 'me', que devuelve el usuario actualmente autenticado.
A continuación, te proporciono un ejemplo sencillo de cómo puedes implementar la autenticación con JWT en NestJS.
Primero, definimos la estrategia JWT:
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
constructor(private readonly authService: AuthService) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: 'SECRET_KEY', // Note: Always store your secret key in an environment variable
});
}
async validate(payload: any) {
const user = await this.authService.validateUser(payload);
if (!user) {
throw new UnauthorizedException();
}
return user;
}
}
Aquí, el método validate()
recibe el payload del token desencriptado. Si la validación del usuario falla, se lanza una excepción UnauthorizedException
.
A continuación, definimos un controlador de autenticación simple:
@Controller('auth')
export class AuthController {
constructor(private authService: AuthService) {}
@Post('login')
async login(@Body() loginUserDto: LoginUserDto): Promise<any> {
return this.authService.login(loginUserDto);
}
@UseGuards(AuthGuard('jwt'))
@Get('profile')
getProfile(@Request() req) {
return req.user;
}
}
En el controlador
de autenticación, la ruta de 'login' autentica a los usuarios y devuelve un JWT. La ruta 'profile' está protegida por la estrategia JWT, y devuelve el perfil del usuario actualmente autenticado.
Por último, el módulo de autenticación podría verse así:
@Module({
providers: [AuthService, JwtStrategy],
controllers: [AuthController],
imports: [
PassportModule.register({ defaultStrategy: 'jwt' }),
JwtModule.register({
secret: 'SECRET_KEY', // Note: Always store your secret key in an environment variable
signOptions: { expiresIn: '60s' },
}),
],
})
export class AuthModule {}
En el módulo de autenticación, importamos PassportModule
y JwtModule
, y proporcionamos AuthService
y JwtStrategy
.
Recuerda siempre asegurarte de que tu clave secreta JWT se mantiene en un lugar seguro y no está codificada en el código fuente. También es importante manejar adecuadamente los errores y proporcionar una respuesta útil cuando ocurre un error de autenticación.