# Guia de Uso: JWT Authentication (NestJS) **Modulo:** auth-jwt-nestjs **Version:** 2.1.0 --- ## Prerequisitos - [ ] NestJS 9+ configurado - [ ] PostgreSQL con tabla `users` - [ ] Redis (opcional, para blacklist de tokens) - [ ] Variables de entorno configuradas ## Paso 1: Instalar Dependencias ```bash npm install @nestjs/jwt @nestjs/passport passport passport-jwt bcrypt class-validator class-transformer npm install -D @types/passport-jwt @types/bcrypt ``` ## Paso 2: Variables de Entorno ```env # JWT JWT_SECRET=your-super-secret-key-min-32-chars JWT_EXPIRES_IN=15m JWT_REFRESH_SECRET=your-refresh-secret-key-min-32-chars JWT_REFRESH_EXPIRES_IN=7d # Opcional: Multi-tenant MULTI_TENANT_ENABLED=false # Opcional: Redis para blacklist REDIS_HOST=localhost REDIS_PORT=6379 ``` ## Paso 3: Copiar Modulo ```bash # Desde gamilit (recomendado) cp -r projects/gamilit/apps/backend/src/modules/auth \ your-project/src/modules/ # O desde erp-core cp -r projects/erp-core/backend/src/modules/auth \ your-project/src/modules/ ``` ## Paso 4: Integrar en AppModule ```typescript // app.module.ts import { AuthModule } from './modules/auth/auth.module'; import { UsersModule } from './modules/users/users.module'; @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true }), AuthModule, UsersModule, // ... otros modulos ], }) export class AppModule {} ``` ## Paso 5: Configurar JWT Strategy ```typescript // auth/strategies/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('JWT_SECRET'), }); } async validate(payload: any) { return { id: payload.sub, email: payload.email, roles: payload.roles, tenantId: payload.tenantId, // Si multi-tenant }; } } ``` ## Paso 6: Proteger Endpoints ```typescript // cualquier.controller.ts import { Controller, Get, UseGuards } from '@nestjs/common'; import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard'; import { CurrentUser } from '../auth/decorators/current-user.decorator'; @Controller('protected') @UseGuards(JwtAuthGuard) export class ProtectedController { @Get() getProtectedData(@CurrentUser() user: any) { return { message: 'Protected data', userId: user.id }; } } ``` ## Paso 7: Endpoints Publicos ```typescript // auth.controller.ts import { Public } from './decorators/public.decorator'; @Controller('auth') export class AuthController { @Public() // Excluye de JwtAuthGuard @Post('login') async login(@Body() loginDto: LoginDto) { return this.authService.login(loginDto); } @Public() @Post('register') async register(@Body() registerDto: RegisterDto) { return this.authService.register(registerDto); } } ``` ## Verificacion ### Tests ```bash # Login curl -X POST http://localhost:3000/auth/login \ -H "Content-Type: application/json" \ -d '{"email":"user@example.com","password":"password123"}' # Acceso protegido curl http://localhost:3000/protected \ -H "Authorization: Bearer YOUR_TOKEN" ``` ### Checklist - [ ] Dependencias instaladas - [ ] Variables de entorno configuradas - [ ] AuthModule importado en AppModule - [ ] JwtStrategy configurado - [ ] Endpoints de login/register funcionan - [ ] Endpoints protegidos requieren token --- ## Personalizacion ### Agregar Roles ```typescript // guards/roles.guard.ts @Injectable() export class RolesGuard implements CanActivate { constructor(private reflector: Reflector) {} canActivate(context: ExecutionContext): boolean { const requiredRoles = this.reflector.getAllAndOverride('roles', [ context.getHandler(), context.getClass(), ]); if (!requiredRoles) return true; const { user } = context.switchToHttp().getRequest(); return requiredRoles.some((role) => user.roles?.includes(role)); } } ``` ### Multi-tenant ```typescript // jwt.strategy.ts - incluir tenantId en payload async validate(payload: any) { return { id: payload.sub, email: payload.email, tenantId: payload.tenantId, }; } // auth.service.ts - incluir en token const payload = { sub: user.id, email: user.email, tenantId: user.tenantId, }; ``` --- **Siguiente:** Ver [API.md](./API.md) para referencia completa