¿Qué es JWT?
JWT (JSON Web Token) es un estándar abierto (RFC 7519) para transmitir información entre partes de forma segura y verificable. Se usa principalmente para autenticación: el servidor genera un token cuando el usuario inicia sesión, y el cliente lo envía en cada request posterior. El servidor puede verificar la autenticidad del token sin consultar una base de datos.
A diferencia de las sesiones tradicionales donde el servidor mantiene estado, con JWT el estado está en el token mismo. El servidor solo necesita la clave secreta para verificar que el token es auténtico y no fue manipulado. Esto lo hace ideal para APIs stateless y arquitecturas distribuidas.
Las tres partes.
Un JWT tiene el formato header.payload.signature, tres partes codificadas en Base64url separadas por puntos. El header es un JSON con el tipo de token ("typ":"JWT") y el algoritmo de firma ("alg":"HS256"). El payload contiene los claims: datos sobre el usuario y el token. La signature es la verificación criptográfica que garantiza que el token no fue alterado.
La signature se calcula aplicando el algoritmo indicado en el header a base64url(header) + "." + base64url(payload) usando la clave secreta del servidor. Si alguien modifica cualquier parte del token, la firma no coincide y el servidor rechaza el token. Es una garantía de integridad, no de confidencialidad: el payload es legible por cualquiera.
El flujo de auth.
El flujo típico: el usuario envía sus credenciales al servidor, el servidor las verifica contra la base de datos, y si son correctas genera un JWT firmado con su clave secreta y lo devuelve al cliente. El cliente guarda el token (idealmente en memoria o en una cookie httpOnly, no en localStorage) y lo envía en el header Authorization: Bearer <token> en cada request.
Cuando el servidor recibe una request con token, verifica la firma usando su clave secreta, comprueba que el token no está expirado (claim exp), y extrae los datos del payload para saber quién hace la request. Todo esto sin tocar la base de datos. El costo: si un token es comprometido antes de expirar, no podés invalidarlo sin implementar una blacklist.
Claims estándar.
Los claims son los campos del payload. Los claims registrados (estándar) más usados son: sub (subject, el ID del usuario), exp (expiration time, timestamp Unix de cuándo expira), iat (issued at, cuándo fue creado), iss (issuer, quién lo emitió) y aud (audience, para quién es). Los claims privados son los que definís vos: rol del usuario, permisos, datos adicionales.
Seguridad y errores.
El error más común es guardar el JWT en localStorage: es accesible desde JavaScript y vulnerable a ataques XSS. Mejor usar cookies httpOnly que el navegador gestiona y que el JavaScript del cliente no puede leer. El segundo error es usar el algoritmo "none" o confundir algoritmos simétricos (HS256, donde todos usan la misma clave) con asimétricos (RS256, con clave pública/privada). El tercero es hacer tokens que nunca expiran: siempre definí exp.
Decodificá ahora.
Si necesitás inspeccionar un JWT, el JWT Decoder de GaloDev decodifica el header y payload, muestra las fechas de expiración en formato legible, y te indica si el token ya expiró. Todo en tu navegador, sin enviar el token a ningún servidor.