Qué es un JWT, en cristiano
Un JWT es una cadena que parece tres trozos al azar separados por puntos: aaa.bbb.ccc.
El primer trozo dice cómo se firmó el token. El segundo guarda los datos de verdad (quién eres, cuándo caduca el token). El tercero es la firma, la prueba de que nadie tocó nada por el camino.
Los dos primeros trozos no están cifrados. Están codificados para que entren en una URL o una cabecera, pero cualquiera que tenga el token puede leerlos. Por eso pegar tu token de producción en un “JWT debugger” cualquiera de internet es exactamente la jugada equivocada: le acabas de dar a esa web una sesión válida para la cuenta a la que pertenece el token.
La forma rápida y segura es hacerlo en tu propio navegador. El decodificador JWT de AldeaCode corre entero en tu pestaña. Pegas el token, te enseña los tres trozos formateados, las fechas convertidas a algo legible, y nada sale de tu ordenador.
Leer la cabecera sin entrar en pánico
La cabecera es un JSON pequeño. Cuando algo va mal, dos campos importan: alg y kid.
alg dice cómo se firma el token. Los valores más comunes son HS256 (un secreto compartido), RS256 y ES256 (par de claves pública y privada). Si alg es none, el token va sin firmar. Lo descartas y llamas a tu equipo de seguridad.
kid es un identificador de clave. Cuando el emisor rota las claves, kid le dice al verificador cuál usar. Si falta kid y tu verificador soporta varias claves, tienes un problema.
El bug clásico aquí se llama “confusión de algoritmo”. Un atacante coge un token firmado con RS256, le cambia el alg a HS256, y lo firma con la clave pública como si fuera un secreto. Si el backend se cree lo que dice la cabecera, el token forjado pasa. El arreglo es fijar el algoritmo en el backend, no creerle al token su palabra.
Leer el payload como un contrato
El payload es donde vive la información de verdad. Los campos que revisas son cortos:
isses el emisor. Tiene que ser el servidor de auth en el que confías.audes la audiencia. Tiene que ser tu servicio, no el de otro.expes cuándo caduca el token.iates cuándo se creó.
Para depurar, cuatro chequeos cubren la mayoría de los bugs:
- ¿Está
expen el futuro según tu reloj? - ¿Es
audtu servicio? - ¿Es
issalguien en quien confías? - ¿Están los timestamps en segundos, no en milisegundos?
El cuarto es el asesino silencioso. Algunas librerías devuelven milisegundos, la mayoría de verificadores JWT esperan segundos. El token parece válido durante treinta mil años, y de repente nada se renueva y nadie sabe por qué. Si depuras desde un servicio Node, el decodificador JWT para Node.js muestra el mismo parseo que aplica jsonwebtoken, y si necesitas convertir el timestamp, el convertidor de timestamps de AldeaCode te dice qué unidad estás mirando y qué fecha significa de verdad.
Qué prueba realmente la firma
La firma es lo que impide que nadie cambie el payload. El verificador recalcula la firma usando el algoritmo de la cabecera, el secreto o la clave pública, y los bytes de la cabecera y el payload. Si el valor recalculado coincide con el tercer trozo, el token no ha sido tocado.
Algunas cosas que la firma no prueba:
- No dice que el token no haya caducado.
- No dice que el usuario no haya cerrado sesión.
- No dice que el token sea para tu servicio.
Después de que la firma pase, todavía tienes que comprobar exp, aud, iss. Una firma válida solo te dice que el token salió del emisor sin tocarse.
Si quieres echar un vistazo a los bytes crudos de la firma (por ejemplo para confirmar que la longitud cuadra con el algoritmo), decodifica el tercer trozo con el codificador Base64. Las firmas HS256 son 32 bytes, las RS256 son 256, las ES256 son 64. Una longitud distinta significa que algo destrozó el token por el camino.
Una rutina de 30 segundos
Cuando un token no se comporta:
- Pégalo en el decodificador JWT, o en la versión para Python si depuras un servicio con
PyJWT. - Lee
algprimero. Cualquier cosa rara, para y audita. - Comprueba que
expesté en el futuro, yiaten el pasado reciente. - Confirma que
audes tu servicio yisses tu servidor de auth. - Si todo parece válido y sigue fallando, el bug está en el lado del verificador, no en el token.
Tres reglas para trabajar con JWTs día a día: nunca pegues tokens de producción en una herramienta que no controlas, fija siempre el algoritmo en el backend, y trata los cuatro chequeos del payload como una checklist en lugar de adivinar. El decodificador, el convertidor de timestamps y el codificador Base64 corren en tu navegador, sin subida, sin log, sin servidores de por medio.