JSON Web Token ( JWT , pronunciación sugerida / dʒɒt / , igual que la palabra "jot" [ 1] ) es un estándar de Internet propuesto para crear datos con firma opcional y/o cifrado opcional cuya carga útil contiene JSON que afirma una cierta cantidad de afirmaciones . Los tokens se firman utilizando un secreto privado o una clave pública/privada .
Por ejemplo, un servidor podría generar un token que tenga la afirmación "iniciado sesión como administrador" y proporcionársela a un cliente. El cliente podría entonces utilizar ese token para demostrar que ha iniciado sesión como administrador. Los tokens pueden estar firmados por la clave privada de una de las partes (normalmente la del servidor) de modo que cualquier parte pueda verificar posteriormente si el token es legítimo. Si la otra parte, por algún medio adecuado y fiable, está en posesión de la clave pública correspondiente, también podrá verificar la legitimidad del token. Los tokens están diseñados para ser compactos, [2] seguros para URL , [3] y utilizables, especialmente en un contexto de inicio de sesión único (SSO) de navegador web . Las afirmaciones JWT se pueden utilizar normalmente para pasar la identidad de usuarios autenticados entre un proveedor de identidad y un proveedor de servicios , o cualquier otro tipo de afirmaciones según lo requieran los procesos empresariales. [4] [5]
JWT se basa en otros estándares basados en JSON: JSON Web Signature y JSON Web Encryption . [1] [6] [7]
HS256
indica que este token está firmado con HMAC-SHA256.{ "alg" : "HS256" , "tipo" : "JWT" }
iat
) y un reclamo personalizado ( loggedInAs
).{ "loggedInAs" : "admin" , "iat" : 1422779638 }
HMAC_SHA256 ( secreto , base64urlEncoding ( encabezado ) + '.' + base64urlEncoding ( carga útil ) )
Las tres partes se codifican por separado utilizando Base64url Encoding RFC 4648 y se concatenan utilizando puntos para producir el JWT:
const token = base64urlEncoding ( encabezado ) + '.' + base64urlEncoding ( carga útil ) + '.' + base64urlEncoding ( firma )
Los datos anteriores y el secreto de "secretkey" crean el token:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb2dnZWRJbkFzIjoiYWRtaW4iLCJpYXQiOjE0MjI3Nzk2Mzh9.gzSraSYS8EXBxLN
_oWnFSRgCzcmJmMjLiuyu5CSpyHI=
(Las cadenas json anteriores están formateadas sin nuevas líneas ni espacios, en matrices de bytes UTF-8. Esto es importante ya que incluso cambios leves en los datos afectarán el token resultante)
Este token resultante se puede pasar fácilmente a HTML y HTTP . [3]
En la autenticación, cuando un usuario inicia sesión correctamente, se suele devolver un token web JSON (JWT). Este token debe enviarse al cliente mediante un mecanismo seguro, como una cookie exclusiva de HTTP . No se recomienda almacenar el JWT localmente en mecanismos de almacenamiento del navegador, como el almacenamiento local o de sesión . Esto se debe a que JavaScript que se ejecuta en el lado del cliente (incluidas las extensiones del navegador) puede acceder a estos mecanismos de almacenamiento, lo que expone el JWT y compromete la seguridad. En el caso de procesos desatendidos, el cliente también puede autenticarse directamente generando y firmando su propio JWT con un secreto compartido previamente y pasándolo a un servicio compatible con OAuth de la siguiente manera:
POST /oauth2/token Tipo de contenido: aplicación / x-www-form-urlencoded tipo_concesión = urn:ietf:params:oauth:tipo-concesión:jwt-bearer & aserción = eyJhb...
Si el cliente pasa una aserción JWT válida, el servidor generará un access_token válido para realizar llamadas a la aplicación y lo pasará de vuelta al cliente:
{ "access_token" : "eyJhb..." , "token_type" : "Portador" , "expires_in" : 3600 }
Cuando el cliente desea acceder a una ruta o un recurso protegido, el agente de usuario debe enviar el JWT, normalmente en el Authorization
encabezado HTTP mediante el Bearer
esquema. El contenido del encabezado podría ser similar al siguiente:
Autorización: Portador eyJhbGci ...<snip>... yu5CSpyHI
Este es un mecanismo de autenticación sin estado, ya que el estado del usuario nunca se guarda en la memoria del servidor. Las rutas protegidas del servidor comprobarán si hay un JWT válido en el encabezado de autorización y, si está presente, se permitirá al usuario acceder a los recursos protegidos. Como los JWT son autónomos, toda la información necesaria está allí, lo que reduce la necesidad de consultar la base de datos varias veces.
Existen implementaciones de JWT para muchos lenguajes y marcos, incluidos, entre otros:
Los tokens web JSON pueden contener el estado de la sesión. Pero si los requisitos del proyecto permiten la invalidación de la sesión antes de la expiración del JWT, los servicios ya no pueden confiar en las afirmaciones del token solo por el token. Para validar que la sesión almacenada en el token no se revoque, las afirmaciones del token deben verificarse con un almacén de datos . Esto hace que los tokens ya no sean apátridas, lo que socava la ventaja principal de los JWT. [36]
El consultor de seguridad Tim McLean informó sobre vulnerabilidades en algunas bibliotecas JWT que usaban el alg
campo para validar tokens de manera incorrecta, generalmente al aceptar un alg=none
token. Si bien estas vulnerabilidades fueron corregidas, McLean sugirió descontinuar el alg
campo por completo para evitar una confusión de implementación similar. [10] Aún así, se siguen encontrando nuevas alg=none
vulnerabilidades en circulación, con cuatro CVE presentados en el período 2018-2021 que tienen esta causa. [37] [ se necesita una mejor fuente ]
Con un diseño adecuado, los desarrolladores pueden abordar las vulnerabilidades de los algoritmos tomando precauciones: [38] [39]
alg
campo)En 2017 se descubrió que varias bibliotecas JWT eran vulnerables a un ataque de curva elíptica no válida. [40]
Algunos han argumentado que los tokens web JSON son difíciles de usar de forma segura debido a los muchos algoritmos y opciones de cifrado diferentes disponibles en el estándar, y que se deberían usar estándares alternativos tanto para los frontends web [41] como para los backends. [42]