Sto costruendo un sito Web utilizzando Node ed Express JS e desidero limitare i tentativi di accesso non validi. Entrambi per prevenire il cracking online e per ridurre le chiamate di database non necessarie. Quali sono alcuni modi in cui posso implementarlo?Prevenzione della forza bruta tramite Node ed Express JS
risposta
Forse qualcosa di simile potrebbe aiutarti a iniziare.
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);
Così, dopo aver fatto qualche ricerca, non ero in grado di trovare una soluzione che mi piaceva così ho scritto la mia base di soluzione di Trevor ed esprimere-bruta. Lo puoi trovare here.
ok, ho trovato la soluzione del tentativo di accesso massimo sulla password errata in mangusta ed expressjs.questa è una soluzione. * Per prima cosa definiremo lo schema utente * in secondo luogo definiremo il login massimo sulla funzione di gestione password errata. * terzo quando creeremo l'API di accesso quindi controlleremo questa funzione che quante volte il login utente con password.so sbagliato essere pronti per il codice
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);
};
Ecco la mia funzione di login dove abbiamo verificato la max tentativo di accesso su password.so sbagliato chiameremo questa funzione
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.' });
});
}
});
});
}));
il mio file config.js è qui –
Dai un'occhiata a questo: 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.
Questo riempirà lentamente la tua RAM dal momento che gli IP falliti non vengono mai cancellati da "errori" se un login non riesce mai effettivamente. – josh3736
@ josh3736 Buon punto. Aggiunta una funzione per ripulirla ogni 30 minuti. –
Cosa ne pensi di soluzioni come la bruta-espresse? https://npmjs.org/package/express-brute – Dave