Введение
аналогичный вопрос можно ответить, прежде чем Prevent PHP script from being flooded, но это могло бы не будет достаточных оснований:
- Он использует
$_SERVER["REMOTE_ADDR"]
и они являются некоторые общие соединения имеют одинаковый Public IP Address
- Есть так много
Firefox addon
, которые могут позволяет пользователям использовать несколько прокси-сервер для каждого запроса
Несколько запросов! = Несколько Загрузить
Предотвращение множественного запроса полностью отличается от множественного скачивания почему?
Lest Представьте файл 10MB
, который будет принимать 1min
для загрузки, если вы ограничить доступ пользователей сказать 100 request per min
, что это означает, что вы получили доступ к пользователю, чтобы загрузить
10MB * 100 per min
Чтобы устранить эту проблему, вы можете посмотреть на Download - max connections per user?.
Multiple Запрос
Назад к странице доступа вы можете использовать SimpleFlood
, которые проходят memcache
ограничить пользователей в секунду.Он использует cookies
для решения общей проблемы соединения и пытается получить реальный IP-адрес
$flood = new SimpleFlood();
$flood->addserver("127.0.0.1"); // add memcache server
$flood->setLimit(2); // expect 1 request every 2 sec
try {
$flood->check();
} catch (Exception $e) {
sleep(2); // Feel like wasting time
// Display Captcher
// Write Message to Log
printf("%s => %s %s", date("Y-m-d g:i:s"), $e->getMessage(), $e->getFile());
}
Пожалуйста, обратите внимание, что SimpleFlood::setLimit(float $float);
принимает поплавки, так что вы можете иметь
$flood->setLimit(0.1); // expect 1 request every 0.1 sec
Класс Б
class SimpleFlood extends \Memcache {
private $ip;
private $key;
private $prenalty = 0;
private $limit = 100;
private $mins = 1;
private $salt = "I like TO dance A #### Lot";
function check() {
$this->parseValues();
$runtime = floatval($this->get($this->key));
$diff = microtime(true) - $runtime;
if ($diff < $this->limit) {
throw new Exception("Limit Exceeded By : $this->ip");
}
$this->set($this->key, microtime(true));
}
public function setLimit($limit) {
$this->limit = $limit;
}
private function parseValues() {
$this->ip = $this->getIPAddress();
if (! $this->ip) {
throw new Exception("Where the hell is the ip address");
}
if (isset($_COOKIE["xf"])) {
$cookie = json_decode($_COOKIE["xf"]);
if ($this->ip != $cookie->ip) {
unset($_COOKIE["xf"]);
setcookie("xf", null, time() - 3600);
throw new Exception("Last IP did not match");
}
if ($cookie->hash != sha1($cookie->key . $this->salt)) {
unset($_COOKIE["xf"]);
setcookie("xf", null, time() - 3600);
throw new Exception("Nice Faking cookie");
}
if (strpos($cookie->key, "floodIP") === 0) {
$cookie->key = "floodRand" . bin2hex(mcrypt_create_iv(50, MCRYPT_DEV_URANDOM));
}
$this->key = $cookie->key;
} else {
$this->key = "floodIP" . sha1($this->ip);
$cookie = (object) array(
"key" => $this->key,
"ip" => $this->ip
);
}
$cookie->hash = sha1($this->key . $this->salt);
$cookie = json_encode($cookie);
setcookie("xf", $cookie, time() + 3600); // expire in 1hr
}
private function getIPAddress() {
foreach (array(
'HTTP_CLIENT_IP',
'HTTP_X_FORWARDED_FOR',
'HTTP_X_FORWARDED',
'HTTP_X_CLUSTER_CLIENT_IP',
'HTTP_FORWARDED_FOR',
'HTTP_FORWARDED',
'REMOTE_ADDR'
) as $key) {
if (array_key_exists($key, $_SERVER) === true) {
foreach (explode(',', $_SERVER[$key]) as $ip) {
if (filter_var($ip, FILTER_VALIDATE_IP) !== false) {
return $ip;
}
}
}
}
return false;
}
}
Заключение
Это основные доказать концепции и дополнительные слои могут быть добавлены к нему, таким как
- установить различный предел для различия URLS
- Добавить поддержку наказаний, где вы блокируете пользователь для определенного количества минут или часы
- обнаружения и различные предельная для
Tor
соединений
- т.д.
Это простой класс, который выглядит хорошо. Thx для обмена! –