Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

178
Views
Problema al implementar la funcionalidad de restablecimiento de contraseña (evitando que los usuarios usen contraseñas antiguas) - MongoDB y NodeJS

Estoy implementando la autenticación para una aplicación web y quiero implementar la funcionalidad de contraseña olvidada/restablecida, y se supone que el usuario no debe ingresar contraseñas usadas antiguas al restablecer su contraseña. Mi pregunta especifica es esta:

Tengo 1 modelo de usuario de mangosta que se parece a esto:

 const UserSchema = new mongoose.Schema({ email: { type: String, required: true, unique: true, }, password: { type: String, required: true, select: false, }, passwordChangedAt: { type: Date, required: false, default: null, }, role: { type: mongoose.Schema.Types.ObjectId, ref: 'Role', required: true, }, ...Base, });

También tengo un modelo de restablecimiento de contraseña:

 const PasswordResetSchema = new mongoose.Schema({ user: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true, }, token: { type: String, required: true, }, isUsed: { type: Boolean, required: false, default: false, }, expireDate: { type: Date, required: true, }, oldPassword: { type: String, required: true, }, newPassword: { type: String, required: false, default: null, }, ...Base, });

Ahora, al restablecer la contraseña, quiero buscar en las tablas de restablecimiento de contraseña y verificar si OldPassword o newPassword ya se usaron antes, y si se usaron, mostrar un error al usuario que ya usó esa contraseña una vez. Utilizo bcrypt para hash la contraseña usando un salt, lo que significa que la misma contraseña puede tener un hash diferente en la base de datos. Entonces, el problema es cuando se consulta la colección de restablecimiento de contraseña, para el mismo uso de contraseñas anterior, ¿hay alguna manera de consultar las contraseñas mientras se comparan los hash y la nueva contraseña de texto sin formato para verificar si se usó la contraseña?

 const hashedPassword = await bcrypt.hash(password, bcrypt.genSaltSync()); // Here the hashedPassword is different, since the salt is different const usedSamePassPreviously = await PasswordReset.find({ _id: { $nin: [passwordReset._id] }, user: user._id, $or: [{ oldPassword: hashedPassword }, { newPassword: hashedPassword }], isUsed: true, });

También intenté consultar usando la cláusula $where en mongo, que me permite usar la función JavaScript pura, pero allí no tenemos acceso a la función bcrypt.compare. No quiero cargar todos los datos en el back-end y luego encontrar si se usó una contraseña, o usar la misma sal para todas las contraseñas, ya que eso es un problema de seguridad. ¿Cómo puedo abordar esta consulta? ¿Es posible lograr esto en el lado de la base de datos? Gracias por adelantado.

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

Deberá iterar sobre los hash de todas sus contraseñas prohibidas y usar el método .compare() de bcrypt en cada una. De esa manera, puede ver si el nuevo valor de contraseña que le presentó su usuario debe rechazarse como un duplicado.

Haz esto en tu código de cliente.

Es cierto que hacer .compare() toma tiempo; eso es una característica de diseño. Esa es una razón por la que no debe hacerlo en su servidor de base de datos: la base de datos es un recurso compartido y no desea realizar operaciones de ejecución prolongada que requieran mucha CPU allí; tomarán la CPU necesaria para servir otro código de cliente de base de datos. Realice esas operaciones en su código nodejs. Si el rendimiento es realmente un problema, considere usar un subproceso de trabajo.

Y considere la implicación de seguridad de la información: para hacer esto en su base de datos, debe enviarle la contraseña secreta en texto sin formato que le presentó su usuario. Debe evitar enviar secretos a cualquier lugar donde no sean absolutamente necesarios. El software de base de datos es grande y complejo, y presenta una gran superficie de ataque para los ciberdelincuentes. Así que enviarle secretos que no necesita hace que esos secretos sean un poco más vulnerables. Eso es cierto incluso si en realidad no almacenas los secretos.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!