2

スクリプトがフラッディングしないようにしたいのですが、ユーザーがF5キーを押すと、毎回スクリプトが実行されます。

これを防ぎ、2秒ごとに1つのスクリプト実行を許可したいのですが、その解決策はありますか?

4

5 に答える 5

16

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 ) );
    }

}
于 2012-04-14T16:50:10.763 に答える
4
  1. スクリプトの最後の実行時間をデータベースまたはファイルに保存します。
  2. そのファイル/データベースから読み取り、現在の時刻と比較します。
  3. 差が2秒未満の場合は、スクリプトを終了します。
  4. それ以外の場合は、通常どおり続行します。
于 2012-04-14T16:39:40.807 に答える
2

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秒が経過するまでスクリプトを実行できません。

于 2012-04-14T16:43:09.717 に答える
0

最善の方法は、時間をサーバー側に保存することです。クライアント側に情報を残しておけば、簡単にパスできます。

たとえば、タイムスタンプをテーブルに保存します。これにより、スクリプトのスパムを入力してチェックします。そして、許容範囲を設定するのは簡単でしょう。

于 2012-04-14T16:43:56.630 に答える
0

apcキャッシュまたはmencacheのいずれかを使用して、データベースに保存したり、ファイルから読み取ったりする情報を保存します。時間とリソースを消費すると思います。

于 2012-04-14T18:07:27.940 に答える