Buenas prácticas de seguridad con JWT en producción (algorithms, exp, aud/iss y revocación)
Keyword objetivo: buenas practicas seguridad jwt producción
Si usas JWT en producción, estas prácticas te evitarán incidentes: algoritmos permitidos, expiraciones cortas, rotación de claves y validación de claims.
Contexto y objetivo
JWT es cómodo, pero también es una fuente habitual de fallos de seguridad cuando se valida mal: aceptar alg=none, no comprobar aud/iss, expiraciones eternas o no rotar claves. En equipos con varios servicios, un error en un microservicio puede abrir la puerta a escaladas.
Te doy un checklist de configuración segura (backend + infraestructura) y ejemplos listos para copiar.
Pasos recomendados
Define una política: ¿quién emite tokens y quién los consume? Documenta iss/aud por entorno. Esto evita tokens “válidos” en staging que se aceptan en prod.
Fija algoritmos permitidos. No dejes que el token decida el algoritmo. Tu backend decide y rechaza cualquier cosa fuera de lista.
Expiraciones cortas para access tokens (minutos) y refresh tokens por otro canal. Si necesitas sesiones largas, usa refresh tokens y rotación.
Revocación: JWT por sí mismo no se revoca. Soluciones típicas: denylist por jti, TTL corto + rotación de claves, o introspección en proveedores.
Logs y observabilidad: registra kid, issuer, audience, errores de verificación y diferencias de reloj para detectar problemas antes de que el usuario los vea.
Errores típicos y cómo evitarlos
Aceptar tokens sin exp por compatibilidad “temporal” y olvidarlo: termina siendo permanente.
Usar el mismo issuer/audience en todos los entornos: facilita confusiones y bypasses.
Guardar JWT en localStorage en SPAs sin medidas anti-XSS: un XSS se convierte en robo de sesión.
Verificar firma pero no claims: un token firmado de otro cliente podría colarse si aud no se valida.
No controlar tamaño: tokens gigantes pueden afectar performance o logs.
Ejemplos prácticos con código
// Express + jsonwebtoken - lista blanca de algoritmos
jwt.verify(token, publicKey, { algorithms: ["RS256"], issuer: "https://tu-idp.com", audience: "api://tu-app" });
// Nginx - bloquear tokens en querystring (mejor en header Authorization)
if ($arg_token != "") { return 400; }
// PHP - comprobar exp y aud (concepto)
if (!isset($payload->exp) || time() >= $payload->exp) { throw new Exception("expired"); }
if ($payload->aud !== "api://tu-app") { throw new Exception("bad aud"); }
Checklist final para producción
- Permite explícitamente algorithms (lista blanca).
- Rechaza tokens sin exp, o impón max TTL.
- Valida issuer (iss) y audience (aud).
- Aplica clock skew controlado (no infinito).
- Gestiona revocación (denylist/rotación/short TTL).
Herramientas recomendadas
Preguntas frecuentes
¿JWT reemplaza sesiones tradicionales?
Depende. JWT facilita escalado sin estado, pero requiere disciplina: expiraciones, refresh, revocación y rotación de claves.
¿HS256 o RS256?
HS256 es simple pero requiere compartir secret; RS256 separa firmar/verificar y es ideal con proveedores externos o microservicios.
¿Dónde guardar el token en el front?
Preferible en cookies HttpOnly con SameSite según tu arquitectura; evita exponerlo a XSS.