¿Qué es JSON Web Token (JWT)?
Obtén una clara comprensión de los fundamentos de JSON Web Token (JWT) en 5 minutos.
El JSON Web Token (JWT) se utiliza ampliamente en las aplicaciones web modernas y en los estándares abiertos como OpenID Connect, facilitando la autenticación y la autorización. Aunque el oficial RFC 7519 sirve como una referencia esencial, será desafiante para los principiantes entenderlo. En este artículo, nos centraremos en los conceptos básicos de JWT y los presentaremos en un lenguaje sencillo con ejemplos.
¿Por qué necesitamos JWT?
Hoy en día, es bastante común usar JSON para intercambiar datos entre dos partes. Considera un objeto JSON que representa a un usuario:
sub
es una abreviatura de "sujeto", que es una afirmación estándar en OpenID Connect para representar el identificador del usuario (ID de usuario).
¿Cómo podemos garantizar la integridad de este objeto JSON? En otras palabras, ¿cómo podemos asegurarnos de que los datos no sean manipulados durante la transmisión? Una solución común es utilizar firmas digitales. Por ejemplo, podemos usar criptografía de clave pública: el servidor firma el objeto JSON con su clave privada, y el cliente puede verificar la firma con la clave pública del servidor.
En resumen, JWT ofrece un enfoque estandarizado para representar el objeto JSON y su firma.
El formato de JWT
Dado que existen muchos algoritmos para crear firmas digitales, es necesario especificar el algoritmo utilizado para firmar JWT. Esto se logra construyendo un objeto JSON:
alg
es la abreviatura de "algoritmo", ytyp
es la abreviatura de "tipo".
Normalmente, typ
se establece como JWT
en mayúsculas. Para nuestro ejemplo, alg
es HS256
, lo que significa HMAC-SHA256 (lo explicaremos pronto), e indica que estamos utilizando este algoritmo para crear la firma.
Ahora, tenemos todos los ingredientes para un JWT:
- Header JSON: Algoritmo y tipo
- Payload JSON: Los datos reales
- Firma: La firma que engloba el encabezado y el payload
Sin embargo, ciertos caracteres como los espacios y los saltos de línea no son amigables para la transmisión por red. Por lo tanto, el encabezado y el payload necesitan ser codificados en Base64URL. El JWT típico se ve así:
El
.
sirve como el delimitador.
Vamos a juntar todo y crear un JWT:
Encabezado
JSON: {"alg":"HS256","typ":"JWT"}
Codificado en Base64URL: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Payload
JSON: {"sub":"foo","name":"John Doe"}
Codificado en Base64URL: eyJzdWIiOiJmb28iLCJuYW1lIjoiSm9obiBEb2UifQ
Firma
En HMAC-SHA256, la firma se crea con un secreto:
Por ejemplo, con el secreto como some-great-secret
, la firma se convierte en: XM-XSs2Lmp76IcTQ7tVdFcZzN4W_WcoKMNANp925Q9g
.
JWT
El JWT final es:
Este JWT válido se puede verificar por cualquier parte que posea el secreto.
Elige el algoritmo de firma
Como mencionamos anteriormente, existen varios algoritmos para crear firmas digitales. Usamos HS256
como ejemplo, pero puede que no sea suficientemente fuerte ya que el secreto debe ser compartido entre las partes (por ejemplo, el cliente y el servidor).
En escenarios del mundo real, los clientes pueden incluir aplicaciones públicas como aplicaciones React que no pueden mantener el secreto seguro. En consecuencia, el enfoque preferido implica utilizar criptografía de clave pública (es decir, criptografía asimétrica) para firmar el JWT. Comencemos con el algoritmo más popular: RSA.
RSA
RSA, un algoritmo asimétrico, usa un par de llaves: una llave pública y una llave privada. La llave pública se usa para verificar la firma, mientras que la llave privada se usa para firmar.
El JSON para el encabezado de RSA se ve así:
RS256
significa RSA-SHA256, lo que significa que la firma se crea con el algoritmo RSA y la función hash SHA256. También puedes usarRS384
yRS512
para crear firmas con las funciones hash SHA384 y SHA512, respectivamente.
La firma se crea con la llave privada:
De nuevo, podemos juntar estas partes para crear un JWT, y el JWT final se ve así:
Ahora, el cliente puede verificar la firma sin conocer la llave privada.
ECDSA
Aunque RSA es ampliamente adoptado, sufre de tamaños de firma más grandes, a veces superando el tamaño combinado del encabezado y del payload. El Algoritmo de Firma Digital de Curva Elíptica (ECDSA) es otro algoritmo asimétrico que puede crear firmas más compactas y es más eficiente.
Para generar una llave privada para ECDSA, necesitamos elegir una curva. Esto está fuera del alcance de este artículo, pero puedes encontrar más información aquí.
El JSON para el encabezado de ECDSA se ve así:
ES256
significa ECDSA-SHA256, lo que significa que la firma se crea con el algoritmo ECDSA y la función hash SHA256. También puedes usarES384
yES512
para crear firmas con las funciones hash SHA384 y SHA512, respectivamente.
La firma se crea con la llave privada:
El JWT final mantiene la misma estructura que RSA pero con una firma significativamente más corta:
Verifica el JWT
Verificar un JWT es tan sencillo como el proceso inverso de crear un JWT:
- Divide el JWT en tres partes (encabezado, payload y firma) usando
.
como delimitador. - Decodifica el encabezado y el payload con Base64URL.
- Verifica la firma con el algoritmo especificado en el encabezado y la llave pública (para algoritmos asimétricos).
Hay muchas bibliotecas disponibles para ayudar con la verificación del JWT, como jose para Node.js y navegadores web.
Conclusión
En este artículo, explicamos brevemente los conceptos básicos de JWT, junto con una descripción general de cómo crearlo y verificarlo. Muchos detalles aún no se han explorado, y los cubriremos en futuros artículos.
Logto aprovecha estándares abiertos como JWT y OpenID Connect para asegurar tus aplicaciones y APIs con flujos de trabajo simplificados para todos los desarrolladores. Si estás interesado, puedes probarlo gratis (no se requiere tarjeta de crédito).