node.js - rutas - node express api
PrevenciĆ³n de la fuerza bruta usando Node y Express JS (4)
Estoy construyendo un sitio web usando Node y Express JS y me gustaría acelerar los intentos de inicio de sesión no válidos. Tanto para evitar el crackeo en línea como para reducir las llamadas innecesarias a la base de datos. ¿Cuáles son algunas formas en que puedo implementar esto?
okk, encontré la solución de inicio de sesión máximo intentando una contraseña incorrecta en mangosta y expressjs.hay una solución. * primero definiremos el esquema del usuario * en segundo lugar definiremos el inicio de sesión máximo en la función del manejador de contraseñas incorrectas. * tercero, cuando crearemos la API de inicio de sesión, comprobaremos esta función, cuántas veces inicie sesión el usuario con la contraseña incorrecta. Así que esté listo para el código
var config = require(''../config'');
var userSchema = new mongoose.Schema({
email: { type: String, unique: true, required: true },
password: String,
verificationToken: { type: String, unique: true, required: true },
isVerified: { type: Boolean, required: true, default: false },
passwordResetToken: { type: String, unique: true },
passwordResetExpires: Date,
loginAttempts: { type: Number, required: true, default: 0 },
lockUntil: Number,
role: String
});
userSchema.virtual(''isLocked'').get(function() {
return !!(this.lockUntil && this.lockUntil > Date.now());
});
userSchema.methods.incrementLoginAttempts = function(callback) {
console.log("lock until",this.lockUntil)
// if we have a previous lock that has expired, restart at 1
var lockExpired = !!(this.lockUntil && this.lockUntil < Date.now());
console.log("lockExpired",lockExpired)
if (lockExpired) {
return this.update({
$set: { loginAttempts: 1 },
$unset: { lockUntil: 1 }
}, callback);
}
// otherwise we''re incrementing
var updates = { $inc: { loginAttempts: 1 } };
// lock the account if we''ve reached max attempts and it''s not locked already
var needToLock = !!(this.loginAttempts + 1 >= config.login.maxAttempts && !this.isLocked);
console.log("needToLock",needToLock)
console.log("loginAttempts",this.loginAttempts)
if (needToLock) {
updates.$set = { lockUntil: Date.now() + config.login.lockoutHours };
console.log("config.login.lockoutHours",Date.now() + config.login.lockoutHours)
}
//console.log("lockUntil",this.lockUntil)
return this.update(updates, callback);
};
aquí está mi función de inicio de sesión donde hemos comprobado el intento máximo de inicio de sesión en la contraseña incorrecta. Así llamaremos a esta función
User.findOne({ email: email }, function(err, user) {
console.log("i am aurhebengdfhdbndbcxnvndcvb")
if (!user) {
return done(null, false, { msg: ''No user with the email '' + email + '' was found.'' });
}
if (user.isLocked) {
return user.incrementLoginAttempts(function(err) {
if (err) {
return done(err);
}
return done(null, false, { msg: ''You have exceeded the maximum number of login attempts. Your account is locked until '' + moment(user.lockUntil).tz(config.server.timezone).format(''LT z'') + ''. You may attempt to log in again after that time.'' });
});
}
if (!user.isVerified) {
return done(null, false, { msg: ''Your email has not been verified. Check your inbox for a verification email.<p><a href="/user/verify-resend/'' + email + ''" class="btn waves-effect white black-text"><i class="material-icons left">email</i>Re-send verification email</a></p>'' });
}
user.comparePassword(password, function(err, isMatch) {
if (isMatch) {
return done(null, user);
}
else {
user.incrementLoginAttempts(function(err) {
if (err) {
return done(err);
}
return done(null, false, { msg: ''Invalid password. Please try again.'' });
});
}
});
});
}));
Tal vez algo así podría ayudarlo a comenzar.
var failures = {};
function tryToLogin() {
var f = failures[remoteIp];
if (f && Date.now() < f.nextTry) {
// Throttled. Can''t try yet.
return res.error();
}
// Otherwise do login
...
}
function onLoginFail() {
var f = failures[remoteIp] = failures[remoteIp] || {count: 0, nextTry: new Date()};
++f.count;
f.nextTry.setTime(Date.now() + 2000 * f.count); // Wait another two seconds for every failed attempt
}
function onLoginSuccess() { delete failures[remoteIp]; }
// Clean up people that have given up
var MINS10 = 600000, MINS30 = 3 * MINS10;
setInterval(function() {
for (var ip in failures) {
if (Date.now() - failures[ip].nextTry > MINS10) {
delete failures[ip];
}
}
}, MINS30);
Entonces, después de hacer algunas búsquedas, no pude encontrar una solución que me gustara, así que escribí la mía basada en la solución de Trevor y en la expresión bruta. Puedes encontrarlo aquí .
Eche un vistazo a esto: https://github.com/AdamPflug/express-brute A brute-force protection middleware for express routes that rate-limits incoming requests, increasing the delay with each request in a fibonacci-like sequence.