He implementado un sistema de autenticación sin contraseña (donde los usuarios solo inician sesión con un "enlace mágico" enviado a su correo electrónico) por mi cuenta. Sé que diseñar sistemas de seguridad sin experiencia es realmente malo, así que pregunto si mi sistema tiene algún agujero obvio. Así es como funciona:
- El usuario escribe su correo electrónico & un nombre de usuario único en el cliente JS (SPA)
- El correo electrónico & el nombre de usuario se envía a mi servidor API (en GET / cadena de consulta)
- El servidor de API consulta la Base de datos de usuarios (consulte a continuación el diseño de esta base de datos) para ver si el correo electrónico ya existe
- Si no es así, el correo electrónico se agrega a la base de datos de usuarios junto con el nombre de usuario (nuevo usuario)
- Si lo hace, el servidor API garantiza que el nombre de usuario coincida con el correo electrónico, de lo contrario responde con un error
- El servidor API genera un GUID de alta entropía (cadena larga y aleatoria) y lo almacena en la base de datos de usuarios (en la misma fila que el correo electrónico y el nombre de usuario)
- El servidor API envía al usuario un correo electrónico con un enlace que contiene el GUID en una cadena de consulta a una ruta especial '/ auth /'
- El servidor API almacena la hora exacta en que se envió este correo electrónico en la base de datos de usuarios
- Si el enlace no se presionó dentro de los 30 minutos posteriores a ese tiempo, el GUID se eliminará de la Base de datos de usuarios (para que el usuario tenga que iniciar sesión nuevamente)
- Si se presionó el enlace dentro del tiempo, el servidor API genera un nuevo GUID de sesión, lo almacena en la base de datos de usuarios & pone en una cookie que se intercambia en todas las próximas solicitudes (es decir, cada vez que se produce una nueva solicitud, el servidor API se asegura de que el GUID de sesión coincida con el de la base de datos de usuarios, lo que indica que están conectados)
- El GUID de la sesión se elimina de la base de datos de usuarios si el usuario decide cerrar sesión
- El GUID de la sesión también se elimina cada 3 días (por lo que los usuarios tienen que iniciar sesión cada 3 días)
La base de datos de usuarios tiene las siguientes columnas, con username
como clave principal:
| username | email | magic_link_guid | magic_link_guid_date | session_guid | session_guid_date |
Algunos problemas que no sé cómo solucionar:
- Se realiza una llamada a la base de datos para cada solicitud, que no puede ser buena
- El manejo de los roles de usuario sería realmente difícil con este método
- Esto parece susceptible a los ataques XSS / CRSF
Una vez más, sé que implementar mi propio sistema es malo, pero no puedo encontrar un sistema sin contraseña ya hecho para .NET / C # :(.