Skip to content

Instantly share code, notes, and snippets.

@WanerValencia
Last active February 25, 2024 04:42
Show Gist options
  • Save WanerValencia/770acee7e881dfda96ff2b1f060fabfb to your computer and use it in GitHub Desktop.
Save WanerValencia/770acee7e881dfda96ff2b1f060fabfb to your computer and use it in GitHub Desktop.
Autenticación con JWT y Passport en Nestjs

Autenticación con JWT y Passport en Nestjs

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.

Instalación de dependencias

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:

  1. 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.

  2. 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í.

  3. 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.

Ejemplo de autenticación con JWT

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment