Sistema NEXUS v3.4 migrado con: Estructura principal: - core/orchestration: Sistema SIMCO + CAPVED (27 directivas, 28 perfiles) - core/catalog: Catalogo de funcionalidades reutilizables - shared/knowledge-base: Base de conocimiento compartida - devtools/scripts: Herramientas de desarrollo - control-plane/registries: Control de servicios y CI/CD - orchestration/: Configuracion de orquestacion de agentes Proyectos incluidos (11): - gamilit (submodule -> GitHub) - trading-platform (OrbiquanTIA) - erp-suite con 5 verticales: - erp-core, construccion, vidrio-templado - mecanicas-diesel, retail, clinicas - betting-analytics - inmobiliaria-analytics - platform_marketing_content - pos-micro, erp-basico Configuracion: - .gitignore completo para Node.js/Python/Docker - gamilit como submodule (git@github.com:rckrdmrd/gamilit-workspace.git) - Sistema de puertos estandarizado (3005-3199) Generated with NEXUS v3.4 Migration System EPIC-010: Configuracion Git y Repositorios
210 lines
4.5 KiB
Markdown
210 lines
4.5 KiB
Markdown
# 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<string>('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<string[]>('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
|