JWT explicado: cómo funcionan los tokens web JSON
Los tokens web JSON (JWT) están en todas partes en la autenticación web moderna: inicie sesión en casi cualquier aplicación y probablemente haya un JWT involucrado. Sin embargo, son muy mal entendidos y ese malentendido conduce a verdaderos errores de seguridad. Así es como funcionan realmente, en términos sencillos.
Qué es un JWT
Un JWT es un token compacto y autónomo que transporta información ("reclamaciones") sobre un usuario o sesión. Después de iniciar sesión, un servidor le emite un JWT; lo devuelve con cada solicitud y el servidor confía en él porque está firmado criptográficamente. Es una forma de demostrar que "estoy autenticado" sin que el servidor almacene el estado de la sesión.
Las tres partes
Un JWT consta de tres secciones codificadas en Base64URL separadas por puntos: header.payload.signature.
- Encabezado: el tipo de token y el algoritmo de firma.
- Carga útil: las reclamaciones: ID de usuario, funciones, tiempo de caducidad, etc.
- Firma: un sello criptográfico que demuestra que el token no fue manipulado.
Pegue cualquier token en nuestro decodificador JWT para ver estas partes dispuestas. El estándar está definido en RFC 7519.
La advertencia de seguridad crucial
Este es el error que comete la gente: el encabezado y la carga útil sólo están codificados en Base64, no cifrados. Cualquiera que intercepte un JWT puede decodificar y leer la carga útil al instante. Por lo tanto, nunca coloque secretos (contraseñas, datos personales confidenciales) en una carga útil de JWT. La firma evita la manipulación, no la lectura. (Consulte nuestra guía sobre por qué Base64 no es seguridad.)
Cómo te protege la firma
El servidor firma el token con una clave secreta. Si alguien altera la carga útil, la firma ya no coincide y el servidor la rechaza. Eso es lo que permite al servidor confiar en un token que no almacenó: puede verificar la autenticidad matemáticamente.
La caducidad importa
Debido a que los JWT son autónomos, no es posible "revocar" uno fácilmente antes de que caduque. Es por eso que los tokens bien diseñados incluyen un vencimiento breve (el reclamo exp) y las aplicaciones usan tokens de actualización para emitir tokens nuevos. Los JWT de larga duración suponen un riesgo para la seguridad.
Algoritmos de firma: HMAC vs RSA
El encabezado indica cómo se firma un token y hay dos familias comunes. HMAC (por ejemplo, HS256) utiliza un único secreto compartido para firmar y verificar; es simple, pero cada parte que verifica debe tener el secreto. RSA/ECDSA (por ejemplo, RS256) utiliza una clave privada para firmar y una clave pública separada para verificar, por lo que puede permitir que muchos servicios verifiquen tokens sin compartir el secreto de firma. Para sistemas distribuidos, la firma asimétrica suele ser la opción más segura; para un único backend, HMAC está bien.
Dónde almacenar un JWT en el navegador
Una pregunta práctica de seguridad: ¿dónde reside el token en el lado del cliente? localStorage es conveniente pero legible con cualquier JavaScript, lo que lo hace vulnerable a ataques XSS que roban el token. JavaScript no puede leer una cookie HttpOnly, lo que mitiga XSS, pero necesita protección CSRF. No existe una respuesta perfecta (es una compensación), pero almacenar tokens confidenciales en un localStorage simple en un sitio con algún riesgo XSS es una práctica conocida que vale la pena evitar.
La vulnerabilidad "alg: none"
Un error famoso de JWT: algunas bibliotecas históricamente aceptaban tokens con el algoritmo configurado en "ninguno", lo que significa sin firma alguna, lo que permitía a los atacantes falsificar cualquier carga útil que quisieran. La lección es verificar siempre la firma con un algoritmo esperado explícito y nunca confiar en el algoritmo que declara el propio token. Utilice una biblioteca bien mantenida, fije el algoritmo y un JWT seguirá siendo una credencial sólida y a prueba de manipulaciones.
Conclusión
Un JWT es un token autónomo y firmado que consta de tres partes Base64URL: encabezado, carga útil y firma. La firma garantiza la integridad, pero cualquiera puede leer la carga útil, así que mantén los secretos fuera de ella, establece vencimientos breves y decodifica tokens con una herramienta cuando necesites inspeccionarlos.