Skip to content

Instantly share code, notes, and snippets.

@madkoding
Last active December 15, 2023 14:23
Show Gist options
  • Save madkoding/85379ecaac95cda150262298ed0befcb to your computer and use it in GitHub Desktop.
Save madkoding/85379ecaac95cda150262298ed0befcb to your computer and use it in GitHub Desktop.
Autenticación de JWT con firma RS256 en Nest

Configuración Correcta de JWT en NestJS con firma RS256

Este resumen proporciona una guía sobre cómo configurar correctamente JWT en NestJS, especialmente para el uso de algoritmos RSA como RS256.

Problema Común

El problema suele estar en la configuración incorrecta del JwtModule y la instancia de JwtStrategy. Es crucial especificar los algoritmos utilizados para firmar y verificar los tokens, junto con las claves correspondientes.

Verificación del Algoritmo del Token

Para verificar si los tokens se generan con el algoritmo RS256, revisa el encabezado del token en jwt.io. Si muestra HS256, significa que el algoritmo correcto no se usó para firmar el token.

Generación de Tokens Firmados con RSA

Configuración del Módulo JWT

@Module({
  imports: [
    ConfigModule,
    JwtModule.registerAsync({
      imports: [ConfigModule],
      useFactory: async (configService: ConfigService) => {
        const options: JwtModuleOptions = {
          privateKey: configService.get('JWT_PRIVATE_KEY'),
          publicKey: configService.get('JWT_PUBLIC_KEY'),
          signOptions: {
            expiresIn: '3h',
            algorithm: 'RS256',
          },
        };
        return options;
      },
      inject: [ConfigService],
    }),
  ],
  providers: [AuthService, JwtStrategy],
  exports: [AuthService],
  controllers: [AuthController],
})
export class AuthModule {}

Servicio de Autenticación

@Injectable()
export class AuthService {
  constructor(private jwtService: JwtService) {}

  async generateToken(user: User, signOptions: jwt.SignOptions = {}): Promise<AuthJwtToken> {
    const payload = { sub: user.id, email: user.email, scopes: user.roles };
    return {
      accessToken: this.jwtService.sign(payload, signOptions),
    };
  }
}

Estrategia JWT

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor(private configService: ConfigService) {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: configService.get('JWT_PUBLIC_KEY'),
      algorithms: ['RS256'],
    });
  }

  async validate(payload: any) {
    const { sub: userId, email, scopes: roles } = payload;
    return {
      id: userId,
      email,
      roles,
    };
  }
}

Uso en Otros Microservicios

Puedes usar la misma JwtStrategy en otros microservicios. Comparte la PUBLIC_KEY con los otros servicios, ya sea manualmente o a través de un endpoint de API. Recuerda no compartir ni exponer la PRIVATE_KEY.

Nota: Este código asume la existencia de un ConfigService que proporciona el par de claves RSA desde variables de entorno. Se sugiere encarecidamente

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