El token debe tener al menos 72 bits de entropía (9 bytes o 12 caracteres Base64)
Esto se debe generar con un PSRNG seguro (generador de números aleatorios). Por lo tanto, no utilice el simple operador rand()
de su lenguaje de programación ya que podría ser predecible, pero busque el generador aleatorio seguro que PHP proporciona internamente, o lea los bytes de /dev/urandom
almacenar los enlaces generados en una tabla de base de datos
Es mejor no almacenar el token plano en la base de datos, en caso de que la base de datos sea parcialmente robada. En su lugar, almacene un hash SHA-256 del token, para que la única copia del token original se encuentre en el correo electrónico que envió al cliente.
Tenga en cuenta que el hashing también es común para las contraseñas, pero como las contraseñas tienen menos entropía, normalmente usaría BCrypt. Dado que los tokens tienen 72 bits de entropía, el hash SHA rápido funcionará bien.
ID de token y cliente en la URL
en caso de que el token no coincida con el almacenado para la identificación del cliente, reinicie el token (para evitar el forzamiento brutal)
Yo diría que esto no es necesario. Con 72 bits de entropía, será casi imposible forzar la fuerza bruta del token.
También este esquema sugiere que cualquier persona no autorizada podría restablecer los tokens de esta manera, que es una forma de ataque de DOS. (no pirateando, pero evitando que otros puedan usar el sistema)
haga que los enlaces sean de un solo uso
Esta es una buena opción, porque el enlace se almacenará en el historial del navegador, lamentablemente.
establecer un tiempo de caducidad en los enlaces
Ciertamente es una buena idea.
Sin embargo, tenga en cuenta que el enlace más débil es la capacidad de alguien para piratear el correo electrónico de su cliente (que generalmente se sincroniza en múltiples dispositivos), por lo que no es suficiente seguridad para muchas situaciones, pero puede ser aceptable en su caso. Esa es tu decisión.
Estoy buscando alguna recomendación sobre este enfoque, y ¿cómo puedo mejorarlo? Qué me perdí ? ¿Qué riesgos quedan con este enfoque y cómo superarlos?
He descrito lo que se perdió anteriormente y el principal riesgo de utilizar este enfoque en general. Sin embargo, agregaría que debe limitar la cantidad de correos electrónicos que una persona recibirá. No desea que un robot complete su formulario de Contraseña olvidada muchas veces, por lo tanto, envíe correo basura a su cliente.
Hay muchas otras consideraciones de seguridad relacionadas con la administración de sesiones, así como con la autenticación en sí misma, pero eso está fuera del alcance de esta respuesta.