Contenido del curso

Fundamentos y Primer CRUD

Base de Datos y Persistencia con TypeORM

User ID automático desde JWT en NestJS

Resumen

Cuando construyes una API con autenticación basada en JWT, hay un detalle que cambia por completo la calidad de tu backend: el user ID no debería viajar en el body del request. Si ya envías un token firmado con tu identificador, tu API debe extraerlo sola y enlazar los recursos al usuario logueado. Aquí te muestro cómo lograrlo en NestJS con Passport y JWT, paso a paso.

¿Por qué no debes pedir el user ID en el body del request?

La razón es doble: redundancia y seguridad. Si tu token ya contiene el identificador del usuario, pedirlo otra vez en el DTO es información duplicada que además abre una puerta peligrosa.

  • Redundancia: el access token ya viaja con el ID firmado dentro del payload, así que el backend puede identificarte sin ayuda extra.
  • Seguridad: si aceptas el user ID por body, un usuario podría crear artículos en nombre de otro usuario, suplantando identidad.
  • Regla de negocio limpia: solo usuarios autenticados crean artículos, y siempre quedan enlazados a su propia sesión.

La única excepción válida sería un rol administrador con permisos explícitos para actuar en nombre de otros, pero esa es otra conversación.

¿Qué pasa si dejo el user ID en el DTO? Cualquier usuario autenticado podría enviar el ID de otro y crear contenido a su nombre. Es un riesgo de seguridad clásico que se evita extrayendo el ID directamente del token.

¿Cómo extraer el user ID desde el token JWT en NestJS?

El flujo aprovecha el método validate de la estrategia de Passport, que recibe el payload ya verificado y lo deja disponible en request.user [3:30].

Tipar el payload con un modelo reutilizable

Lo primero es no perder el tipado. Crea una carpeta models dentro del módulo auth y dentro un archivo payload.model.ts que describa exactamente lo que firmas en el JWT [4:20].

ts export interface PayloadToken { sub: number; }

Este PayloadToken representa el contenido del token: un sub numérico que apunta al primary key del usuario. Si más adelante guardas el email o el rol, los agregas aquí y mantienes consistencia en toda la app.

Usa esa interfaz tanto al firmar el token como al validarlo. Así te aseguras de que el shape sea idéntico en ambos lados:

ts async validate(payload: PayloadToken) { return payload; }

Fíjate que aquí no transformamos el payload, lo devolvemos tal cual. Esa decisión simplifica la lectura porque sabes que request.user tendrá exactamente la forma { sub: number }.

Acceder al request en el controller

En el controller de posts, importa Req desde @nestjs/common y Request desde express. Buena práctica: separa los imports de terceros de los imports propios en bloques distintos [5:40].

ts @UseGuards(JwtAuthGuard) @Post() create(@Req() req: Request, @Body() payload: CreatePostDto) { const user = req.user as PayloadToken; const userId = user.sub; return this.postsService.create(payload, userId); }

El guard se encarga de verificar el token, el método validate deja el payload en req.user, y tú extraes el sub para pasarlo al servicio como segundo parámetro.

¿Cómo recibe el servicio el user ID automatizado?

El CreatePostDto deja de tener userId porque el dato ya no viaja por body. El servicio ahora recibe dos argumentos: el DTO validado y el ID extraído del token [7:10].

ts create(data: CreatePostDto, userId: number) { const newPost = this.postRepo.create(data); newPost.user = { id: userId } as User; return this.postRepo.save(newPost); }

Esta separación deja claro qué viene del cliente (el contenido del post) y qué viene de la sesión (la identidad). Es una división que escala bien cuando agregas más reglas de negocio.

¿Qué es el campo sub en un JWT? Es la abreviación de subject y representa al sujeto del token, normalmente el ID del usuario autenticado. Es el estándar para identificar a quién pertenece la sesión.

¿Cómo se ve esto funcionando en Postman?

La prueba es directa y demuestra el comportamiento esperado. Te logueas con el usuario cinco, copias el access token, lo pegas en el header Authorization y envías un POST a /posts solo con el título y el contenido [8:50].

  • El post queda enlazado automáticamente al usuario cinco.
  • Cambias el token por el del usuario cuatro y el siguiente post queda enlazado al usuario cuatro.
  • En ningún momento envías userId en el body.

Esa es la confirmación de que el backend está identificando al dueño de la sesión y creando el recurso a su nombre, sin exponer un campo manipulable.

Habilidades y conceptos que se ponen en práctica

Este flujo conecta varias piezas de NestJS y autenticación que vale la pena tener claras.

  • JWT (JSON Web Token): estándar para firmar y verificar tokens con un payload, donde guardas el sub con el ID del usuario [0:50].
  • DTO (Data Transfer Object): el CreatePostDto define qué acepta el endpoint, y al quitar userId reduces superficie de ataque [3:00].
  • Passport strategy validate: método que recibe el payload verificado y lo expone en request.user [3:30].
  • Decorador @Req(): te permite acceder al objeto request de Express desde el controller [5:40].
  • Tipado con interfaces: el PayloadToken mantiene consistencia entre el momento de firmar y el de validar el token [4:20].
  • Guards de autenticación: JwtAuthGuard protege la ruta y dispara la verificación del token antes de llegar al controller.

¿Ya estás aplicando esta automatización en tus APIs o todavía pides el user ID por body? Cuéntame en los comentarios cómo manejas tú la identidad del usuario autenticado.