(generado a partir de este hilo ya que esto es realmente una cuestión propia y no específica de NodeJS, etc.)
Estoy implementando un servidor API REST con autenticación, y he implementado con éxito el manejo de tokens JWT para que un usuario pueda iniciar sesión a través de un punto final / login con nombre de usuario / contraseña, tras lo cual se genera un token JWT a partir de un secreto del servidor y se devuelve al cliente. Luego, el token se pasa del cliente al servidor en cada solicitud de API autenticada, tras lo cual se utiliza el secreto del servidor para verificar el token.
Sin embargo, estoy tratando de comprender las mejores prácticas sobre exactamente cómo y en qué medida se debe validar el token para crear un sistema verdaderamente seguro. ¿Exactamente qué debería estar involucrado en "validar" el token? ¿Es suficiente que la firma pueda verificarse usando el secreto del servidor, o también debería verificar el token y / o la carga útil del token con algunos datos almacenados en el servidor?
Un sistema de autenticación basado en token solo será tan seguro como pasar el nombre de usuario / contraseña en cada solicitud, siempre que sea igual o más difícil obtener un token que obtener la contraseña de un usuario. Sin embargo, en los ejemplos que he visto, la única información necesaria para producir un token es el nombre de usuario y el secreto del lado del servidor. ¿No significa esto que asumiendo por un minuto que un usuario malintencionado adquiere conocimiento del secreto del servidor, ahora puede producir tokens en nombre de cualquier usuario, teniendo así acceso no solo a un usuario dado como sería el hecho si una contraseña fuera obtenido, pero de hecho a todas las cuentas de usuario?
Esto me lleva a las preguntas:
1) ¿Debería limitarse la validación del token JWT a verificar la firma del token en sí, confiando únicamente en la integridad del secreto del servidor o acompañada de un mecanismo de validación separado?
En algunos casos, he visto el uso combinado de tokens y sesiones de servidor en las que, al iniciar sesión correctamente a través del punto final / login, se establece una sesión. Las solicitudes de la API validan el token y también comparan los datos decodificados que se encuentran en el token con algunos datos almacenados en la sesión. Sin embargo, usar sesiones significa usar cookies y, en cierto sentido, frustra el propósito de usar un enfoque basado en tokens. También puede causar problemas a ciertos clientes.
Uno podría imaginar que el servidor mantiene todos los tokens actualmente en uso en un Memcache o similar, para asegurarse de que incluso si el secreto del servidor se ve comprometido para que un atacante pueda producir tokens "válidos", solo los tokens exactos que se generaron a través del extremo / login sería aceptado. ¿Es esto razonable o simplemente redundante / excesivo?
2) Si la verificación de la firma JWT es el único medio de validar tokens, lo que significa que la integridad del secreto del servidor es el punto de ruptura, ¿cómo se deben gestionar los secretos del servidor? ¿Leer de una variable de entorno y crear (¿aleatoriamente?) Una vez por pila implementada. Renovado o rotado periódicamente (y si es así, cómo manejar los tokens válidos existentes que se crearon antes de la rotación pero necesitan ser validados después de la rotación, tal vez sea suficiente si el servidor se aferra al secreto actual y anterior en un momento dado) ? ¿Algo más?
Tal vez simplemente estoy siendo demasiado paranoico cuando se trata del riesgo de que el secreto del servidor se vea comprometido, que por supuesto es un problema más general que debe abordarse en todas las situaciones criptográficas ...
RSAPrivateKey privateKey
?