springboot example web-services rest authentication jwt

web services - example - Manejo de la funcionalidad de expiración/"recordarme" con JWT



spring-security-jwt (5)

Conceptualmente, me gusta mucho JWT ya que está en línea con la apatridia de REST, etc. (no se guarda el estado del servidor, todos los datos relevantes están contenidos en el token).

De lo que no estoy seguro: ¿cómo manejarías la caducidad del token cuando no está conectado (es decir, una funcionalidad "recordarme")?

Hay una cobertura emergente de JWT en la web, pero no pude encontrar a nadie que respondiera la pregunta de expiración todavía.

Aclaración: no estoy preguntando cómo manejar un token a punto de caducar, sino qué hacer cuando un token ya ha caducado (el usuario cerró el sitio web / la aplicación por un tiempo). La solución más simple que me viene a la mente es el almacenamiento en caché de las credenciales del usuario, que es bastante inseguro.


Además de la respuesta de @Jesus , puede pensar en implementar un sistema de token de actualización: https://auth0.com/blog/refresh-tokens-what-are-they-and-when-to-use-them/

En el hotel, por ejemplo, su tarjeta de hotel (token de acceso) no sería válida después del tiempo X, pero en la recepción puede usar su pasaporte (refrescar-token) para obtener una nueva tarjeta de hotel nuevamente.

Puede almacenar el token de actualización en la base de datos con datos adicionales sobre el dispositivo que está usando, lo que le permite desactivar el dispositivo en caso de que sea robado.

Ejemplo:

  1. primer inicio de sesión correcto del cliente: cree un token de actualización que sea válido para siempre (hasta que se elimine o invalide)
  2. Almacenar token de actualización en la base de datos
  3. return token de acceso (JWT) con tiempo de vencimiento al cliente (este token no se almacena en la base de datos)
  4. para la próxima solicitud, el cliente envía el token de acceso

  5. Ahora compruebe si el token de acceso ha caducado:

    5.1 Token de acceso no caducado, todo está bien

    5.2 Token de acceso caducado, verifique si hay un token de actualización en la base de datos

    5.2.1 Refresh Token está en la base de datos, devuelve un nuevo token de acceso

    5.2.2 No Token de actualización en la base de datos, return 401 / logout, el usuario tiene que iniciar sesión de nuevo

Espero que esto ayude.


Creo que lo que estás preguntando es cómo invalidar un lado del servidor JWT para los tokens de expiración larga (por ejemplo, la función "recordarme").

Me encontré con este problema recientemente y terminé usando un secreto de usuario único para invalidar el token, cuando el usuario intenta validar un token que se produjo con un antiguo secreto, fallará. El nombre de usuario se puede encontrar en la verificación previa JWT decodificada.

Probablemente puedas usar la contraseña de los usuarios para que, de esta forma, cualquier JWT actual se invalide cuando un usuario cambie su contraseña (suponiendo que también cambies la sal al mismo tiempo), esto puede ser problemático como el hash de la contraseña y el JWT se acoplaría estrechamente


Necesita persistir el JWT en el cliente para que esté disponible en todas las cargas de página, la estrategia más segura es una cookie de solo HTTPS. Esto enviará el JWT a su servidor en cada solicitud y el servidor puede verificar la validez del token y rechazarlo si ha expirado. La forma en que maneje la caducidad depende del tipo de aplicación web que tenga.

Para una aplicación de una sola página (por ejemplo, aplicaciones Angular.js), le conviene estructurar la aplicación para que realice una solicitud inicial del servidor antes de que inicie el resto de la aplicación. Si el servidor ve que el JWT en esta solicitud está vencido, emitirá una respuesta 401. Su aplicación respondería a esta respuesta presentando un formulario de inicio de sesión. De lo contrario, continuaría con la suposición de que el JWT es válido y puede usarse para acceder a los recursos requeridos. Si, en algún momento, la aplicación ve un 401, debería devolver al usuario al formulario de inicio de sesión.

Para aplicaciones web tradicionales que rinden sus páginas en el servidor: para cualquier solicitud que tenga un JWT caducado (tal como se lee de la cookie) el servidor debe emitir un redireccionamiento 302 a un formulario de inicio de sesión.


No estoy seguro de seguirlo, pero escribiré lo que pienso.

Imagina el token como una tarjeta de hotel, pagas por adelantado durante 5 días (recuerda que expirará en 5 días). Puedo ingresar al edificio, el garaje, la habitación, etc. dentro de esos 5 días, después de esos 5 días, ya no funcionará.

¿Qué hacer cuando token ya ha expirado? Nada en absoluto.

Imagine que pagué esos 5 días y meh, tuve urgencia y regreso a casa (con la tarjeta en el bolsillo). Al hotel no le importa en absoluto, cuando pasen los 5 días, la tarjeta es solo una pieza de plástico inútil y si intenta usarla en el hotel, no hará nada.

Entonces volvamos al desarrollo web. Si ofrece un servicio para recordarme, puede poner una fecha de caducidad, digamos 7 días. Siempre que el usuario tenga el token, puede acceder al servicio sin ningún problema. Si pierde el token, necesita iniciar sesión nuevamente. Si usa el token y ha expirado, también deberá volver a iniciar sesión.

Si inicia sesión, obtiene un token durante 7 días, si ya no lo usa y después de 20 días regresa, tendría que volver a iniciar sesión, el servidor rechazará sus peticiones hasta que lo haga.

Lo que haría si utiliza algo como angular en la interfaz es verificar la validación de tokens al inicio para que pueda tener una buena experiencia de usuario.

Lo que no entiendo acerca de tu pregunta es, sin embargo, de caché.


Puedo pensar de una manera, pero en realidad no está definido el estándar.

¿Qué tal agregar otro tipo de fecha de caducidad con una vida útil diferente a las reclamaciones? Con dos reclamaciones, podemos tratar la más corta como la fecha de vencimiento del acceso a los recursos, y la más larga como la fecha de vencimiento de la actualización, por ejemplo

{ "iat": /* current time */, "bbf": /* current time + 1 hour -- expired means no resource access */ "exp": /* current time + 1 week -- expired means cannot refresh */ }

(Nota: uso bbf para la fecha de caducidad más corta. No hay motivo específico, solo porque tiene 3 caracteres de longitud).

Entonces, con "recordarme", cuando el usuario se vuelva a conectar, puede usar el mismo token para solicitar uno nuevo, pero no para acceder al recurso. Con esto, todos los datos relevantes están contenidos dentro del token, no se requiere token adicional.

Y, por último, cuando "recordarme" no está marcado, solo usa la misma duración de vida para bbf y exp .