¿Qué es JSON Web Token?
JSON Web Token (JWT) es un estándar abierto (RFC-7519) basado en JSON para crear un token que sirva para enviar datos entre aplicaciones o servicios y garantizar que sean válidos y seguros.
El caso más común de uso de los JWT es para manejar la autenticación en aplicaciones móviles o web. Para esto cuando el usuario se quiere autenticar manda sus datos de inicio del sesión al servidor, este genera el JWT y se lo manda a la aplicación cliente, luego en cada petición el cliente envía este token que el servidor usa para verificar que el usuario este correctamente autenticado y saber quien es.
Este igual no es el único caso de uso para JWT, es posible usarlo para transferir cualquier datos entre servicios de nuestra aplicación y asegurarnos de que sean siempre válido. Por ejemplo si tenemos un servicio de envío de email otro servicio podría enviar una petición con un JWT junto al contenido del mail o cualquier otro dato necesario y que estemos seguros que esos datos no fueron alterados de ninguna forma.
Estructura de un JWT
Los JWT tienen una estructura definida y estándar basada en tres partes:
header.payload.signature
Las primeras dos partes (header
y payload
) son strings en base64 creados a partir dos JSON. La tercer parte (signature
) toma las otras dos partes y las encripta usando un algoritmo (normalmente SHA-256). Ejemplo:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjEiLCJ1c2VybmFtZSI6InNlcmdpb2R4YSJ9.Qu7rv5wqk6zGjiMU8ZixwvKQGBNW9hhj55DbSP50b1g
Header
El header
de un JWT tiene la siguiente forma:
{
"alg": "HS256",
"typ": "JWT"
}
La propiedad alg
indica el algoritmo usado para en la firma y la propiedad typ
define el tipo de token, en nuestro caso JWT.
Propiedades posibles
- Tipo de token (
typ
) - Identifica el tipo de token. - Tipo de contenido (
cty
) - Identifica el tipo de contenido (siempre debe ser JWT) - Algoritmo de firmado (
alg
) - Indica que tipo de algoritmo fue usado para firmar el token. - Cualquier otro incluido en JWS y JWE.
Payload
El payload
de un JWT es un JSON que puede tener cualquier propiedad, aunque hay una serie de nombres de propiedades definidos en el estándar.
{
"id": "1",
"username": "sergiodxa"
}
Ese es el payload
usado en el JWT de ejemplo.
Propiedades estándar
- Creador (
iss
) - Identifica a quien creo el JWT - Razón (
sub
) - Identifica la razón del JWT, se puede usar para limitar su uso a ciertos casos. - Audiencia (
aud
) - Identifica quien se supone que va a recibir el JWT. Un ejemplo puede serweb
,android
oios
. Quien use un JWT con este campo debe además de usar el JWT enviar el valor definido en esta propiedad de alguna otra forma. - Tiempo de expiración (
exp
) - Una fecha que sirva para verificar si el JWT esta vencido y obligar al usuario a volver a autenticarse. - No antes (
nbf
) - Indica desde que momento se va a empezar a aceptar un JWT. - Creado (
iat
) - Indica cuando fue creado el JWT. - ID (
jti
) - Un identifador único para cada JWT.
Signature
Por último la firma del JWT se genera usando los anteriores dos campos en base64 y una key secreta (que solo se sepa en los servidores que creen o usen el JWT) para usar un algoritmo de encriptación. La forma de hacerlo entonces sería la siguiente (usando pseudo código):
key = 'secret'
unsignedToken = base64Encode(header) + '.' + base64Encode(payload)
signature = SHA256(key, unsignedToken)
token = unsignedToken + '.' + signature
De esta forma obtenemos la firma y la agregamos al final de nuestro JWT.
Implementaciones
JWT se puede usar en prácticamente cualquier lenguaje y hay librerías para crear, leer y verificar JWT en multitud de lenguajes:
.NET
[1] [2]
[3]- Python [1] [2] [3]
- Node.js [1]
- Java [1] [2] [3] [4]
- JavaScript [1]
- Perl [1]
- Ruby [1] [2] [3]
- Elixir [1] [2]
[3] - Go [1] [2] [3] [4]
- Haskell [1] [2]
- Rust [1]
- Lua [1]
- Scala [1] [2] [3]
- D [1]
- Clojure [1]
- Objective-C [1]
- Swift [1]
- C [1]
- kdb+/Q [1]
- Delphi [1]
- PHP [1] [2] [3] [4] [5] [6]
- Crystal [1]