Ограничение скорости для предотвращения злонамеренного поведения в ExpressJS - PullRequest
8 голосов
/ 24 февраля 2012

Кто-то заставил меня заметить некоторые недостатки в приложении, над которым я работаю (в основном в моем JavaScript на внешней стороне), что оставляет открытой возможность, скажем, щелкнуть тонну кнопок одновременно и отправить тонна транзакционных писем. Это явно не хорошо.

Я думаю, что одним из способов справиться с этим в ExpressJS является использование app.all() для подсчета количества запросов, которые происходят в течение определенного периода времени. Я бы сохранял это в метаданных сеанса с временными метками, и если за время Y произошло больше X запросов, я отключил их на некоторое время, пока не истечет лимит.

Кто-нибудь делал это раньше или есть какие-либо советы / подсказки, чтобы помочь мне? Что-то, что легко вставлять и выкидывать из моего приложения, предпочтительнее. Спасибо!

1 Ответ

2 голосов
/ 24 февраля 2012

Вы можете использовать объект Collate на своей веб-странице.

function Collate(timeout) {
  this.timeout = timeout || 1000;
}
Collate.prototype = {
  time: 0,

  idle: function() {
    var t = new Date().getTime();
    return (t - this.time > this.timeout && (this.time = t));
  },

  prefer: function(func) {
    this.func = func;
    clearTimeout(this.timer);
    this.timer = setTimeout(func, this.timeout);
  }
};

Если вы хотите, чтобы функция запускалась один раз и не запускалась снова в течение следующей 1 секунды.Например, если вы хотите запретить пользователю отправлять форму много раз, вы делаете это:

var timer = new Collate(3000);  //3 seconds
button1.onclick = function() {
    if(timer.idle()) {
        button1.form.submit();
    } else alert("Don't click too quickly!");
}

//or on the form tag

<script>var submitTimer = new Collate(3000);</script>
<form action="post" onsubmit="return submitTimer.idle();">

Если вы ожидаете, что событие будет срабатывать несколько раз, и хотите реагировать только на последний раз, когда оно сработало.Например, если вы хотите выполнить поиск после того, как пользователь закончил печатать, вы делаете это:

var timer = new Collate(700); //0.7 seconds
textfield1.onkeyup = function() {
    timer.prefer(function() {
        autocomplete.search(textfield1.value);
    });
};
...