2013-10-30 9 views
6

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

4

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); 
+0

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

+0

@ josh3736 Buon punto. Aggiunta una funzione per ripulirla ogni 30 minuti. –

+2

Cosa ne pensi di soluzioni come la bruta-espresse? https://npmjs.org/package/express-brute – Dave

7

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.

0

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.' }); 
       }); 
      } 
     }); 
    }); 
})); 
+0

il mio file config.js è qui –