スクリプトがフラッディングしないようにしたいのですが、ユーザーがF5キーを押すと、毎回スクリプトが実行されます。
これを防ぎ、2秒ごとに1つのスクリプト実行を許可したいのですが、その解決策はありますか?
memcacheを使用してこれを行うことができます..
簡単なデモスクリプト
$memcache = new Memcache ();
$memcache->connect ( 'localhost', 11211 );
$runtime = $memcache->get ( 'floodControl' );
if ((time () - $runtime) < 2) {
die ( "Die! Die! Die!" );
}
else {
echo "Welcome";
$memcache->set ( "floodControl", time () );
}
これは単なるサンプルコードです..他にも考慮すべきことがあります。
A.より良いIP
アドレス検出(Proxy、Tor)
B.現在のアクション
C.1分あたりの最大実行など..。
D.最大洪水などの後にユーザーを禁止する
編集1-改善されたバージョン
使用法
$flood = new FloodDetection();
$flood->check();
echo "Welcome" ;
クラス
class FloodDetection {
const HOST = "localhost";
const PORT = 11211;
private $memcache;
private $ipAddress;
private $timeLimitUser = array (
"DEFAULT" => 2,
"CHAT" => 3,
"LOGIN" => 4
);
private $timeLimitProcess = array (
"DEFAULT" => 0.1,
"CHAT" => 1.5,
"LOGIN" => 0.1
);
function __construct() {
$this->memcache = new Memcache ();
$this->memcache->connect ( self::HOST, self::PORT );
}
function addUserlimit($key, $time) {
$this->timeLimitUser [$key] = $time;
}
function addProcesslimit($key, $time) {
$this->timeLimitProcess [$key] = $time;
}
public function quickIP() {
return (empty ( $_SERVER ['HTTP_CLIENT_IP'] ) ? (empty ( $_SERVER ['HTTP_X_FORWARDED_FOR'] ) ? $_SERVER ['REMOTE_ADDR'] : $_SERVER ['HTTP_X_FORWARDED_FOR']) : $_SERVER ['HTTP_CLIENT_IP']);
}
public function check($action = "DEFAULT") {
$ip = $this->quickIP ();
$ipKey = "flood" . $action . sha1 ( $ip );
$runtime = $this->memcache->get ( 'floodControl' );
$iptime = $this->memcache->get ( $ipKey );
$limitUser = isset ( $this->timeLimitUser [$action] ) ? $this->timeLimitUser [$action] : $this->timeLimitUser ['DEFAULT'];
$limitProcess = isset ( $this->timeLimitProcess [$action] ) ? $this->timeLimitProcess [$action] : $this->timeLimitProcess ['DEFAULT'];
if ((microtime ( true ) - $iptime) < $limitUser) {
print ("Die! Die! Die! $ip") ;
exit ();
}
// Limit All request
if ((microtime ( true ) - $runtime) < $limitProcess) {
print ("All of you Die! Die! Die! $ip") ;
exit ();
}
$this->memcache->set ( "floodControl", microtime ( true ) );
$this->memcache->set ( $ipKey, microtime ( true ) );
}
}
Cookie(無効にすることができます)を使用してあまり良い考えではないか、データベースに彼のIPアドレスを保存することを使用できます。したがって、Xが同じIPアドレスから試行する場合は、コードを実行せず、コードを実行するだけです。 elseステートメントの場合、IPアドレスを含むテーブルが必要になりますリクエストの時間、試行回数
データベースを使用したくない場合は、次のコードを使用できます
$file = "file.txt";
$file_content = file_get_contents($file);
$fh = fopen($file, 'w') or die("could not open file");
$now = time();
if($now - $file_content > 60){
// your code here
fwrite($fh, $now);
}else{
echo "Try again later";
}
fclose($fh);
ただし、この場合、訪問者ごとではなく、すべての訪問者が対象になります(つまり、ユーザーAが来てスクリプトを実行した場合、ユーザーBは60秒が経過するまでスクリプトを実行できません。
最善の方法は、時間をサーバー側に保存することです。クライアント側に情報を残しておけば、簡単にパスできます。
たとえば、タイムスタンプをテーブルに保存します。これにより、スクリプトのスパムを入力してチェックします。そして、許容範囲を設定するのは簡単でしょう。
apcキャッシュまたはmencacheのいずれかを使用して、データベースに保存したり、ファイルから読み取ったりする情報を保存します。時間とリソースを消費すると思います。