Estoy implementando JWT en mi aplicación y me gustaría hacerlos lo más seguros posible. Presentaré todo lo que estoy planeando, agradecería enormemente cualquier sugerencia en cuanto a la seguridad de esta implementación. Este es mi sitio, tengo acceso completo a todos los aspectos, tanto front-end como back-end.
Esto será un SPA, utilizando una API para acceder al back-end. Estoy usando JWT para guardar llamadas a la base de datos con cada golpe de API.
JWTs
Los JWT se almacenan en una cookie access_token
. Primero se firman y luego se encriptan utilizando jose-jwt . El algoritmo de firma es HS256, el cifrado es DIR. Incluyen la ID del usuario, una caducidad exp
de reclamación y varias otras reclamaciones personalizadas. Los JWT caducan en 30 minutos y la cookie de JWT caduca en 7 días.
(versión corta):
- JWT almacenado en una cookie
- JWT incluye ID de usuario
- JWT firmado y luego encriptado
- Reclamación JWT
exp
establecida en 30 minutos en el futuro - El conjunto de cookies de JWT expirará 7 días en el futuro
Protección CSRF
Los JWT incluyen una reclamación cst
que almacena un token CSRF generado aleatoriamente. El token CSRF se envía en el cuerpo de la respuesta al iniciar sesión y cuando se emite un nuevo JWT. El token CSRF se almacena en el almacenamiento local del navegador. Se envía con cada solicitud y se valida con respecto al valor en el JWT.
(versión corta):
- JWT incluye un token CSRF generado aleatoriamente
- El token CSRF se envía al iniciar sesión y se almacena en localStorage
- token CSRF enviado en el encabezado de solicitud de todas las solicitudes
- El token CSRF del encabezado en comparación con el token CSRF en el JWT
Tokens de actualización
Como los JWT caducan en 30 minutos, es necesario actualizarlos. El JWT incluye una reclamación rfs
que almacena un token de actualización aleatorio. Este token de actualización también se almacena en la base de datos (una tabla separada de los usuarios para permitir múltiples sesiones). Si el JWT ha caducado (según su reclamación exp
), se comprueba la base de datos para garantizar que el usuario sigue siendo válido (por ejemplo, la cuenta no se ha eliminado, la contraseña no se ha cambiado, etc.) Si el usuario es válido, se verifica el token de actualización y se genera un nuevo token JWT / CSRF y se devuelve en la respuesta. Si el usuario no es válido, access_token
se devuelve con un valor arbitrario como 0
, y su vencimiento se establece en el pasado para que el navegador lo elimine. El token CSRF se devuelve vacío para que se borre de localStorage. Todos los tokens de actualización para el usuario se borran de la base de datos.
(versión corta):
- Si JWT expiró, verifique la base de datos del usuario para verificar que el usuario aún es válido
- SI ES VÁLIDO:
- Compare el token de actualización con DB (suponga que coincide con el resto de esto)
- Genere un nuevo token de actualización, sobrescriba el valor anterior en DB
- Vuelva a emitir JWT con la nueva fecha
exp
- Pase el token de actualización y guárdelo en localStorage
- SI NO ES VÁLIDO:
- Borrar la cookie JWT por a) configurando un valor no válido, b) configurando la caducidad como pasada
- Indica al navegador que borre el token CSRF de almacenamiento local
- Borrar todos los tokens de actualización para el usuario de la base de datos
TL rápido y sucio; DR
- Al iniciar sesión, agregue un token CSRF aleatorio al JWT.
- Envíe ese mismo token CSRF al cliente en el cuerpo de la respuesta.
- Almacene el token CSRF en localStorage.
- Incluir un token de actualización en el JWT.
- Configure la cookie JWT para que caduque después de 1 semana.
- Establezca el reclamo de exp JWT en 30 minutos.
- Si la reclamación JWT ha caducado, verifique el token de actualización contra la base de datos para asegurarse de que el usuario sigue siendo válido.
- SI EL USUARIO ES VÁLIDO:
- Emita JWT actualizado con el nuevo token CSRF y el nuevo token de actualización.
- Establezca la caducidad de la cookie JWT en una semana en el futuro. (Vuelva a emitir la cookie, básicamente)
- Envíe un nuevo token CSRF en el cuerpo de la respuesta, sobrescriba el valor de almacenamiento local existente.
- SI EL USUARIO NO ES VÁLIDO:
- Devolver la cookie JWT con el mismo nombre pero sin contenido.
- Establezca el vencimiento de las cookies en una fecha arbitraria en el pasado.
- Indique al navegador que borre el valor de almacenamiento local.