2015-12-26 5 views
5

ユーザーは、script.php?userid=222のようなURLを介して番号でファイルを要求します。この例では、ファイル#222のレコードが表示されます。1分以内に行われるユーザー要求の数を制限する方法

ここでは、(リモートIP)ユーザーあたりのファイル数を1分間に最大5つの異なるレコードに制限したいと考えています。ただし、ユーザーは同じIDレコードに何回もアクセスできなければなりません。

したがって、ユーザーは任意の回数だけファイル#222にアクセスできますが、(リモートIP)ユーザーが1分以内に5つ以上の異なるレコードにアクセスすると、エラーが表示されるはずです。例えば

は、分以内とし、次の要求が行われます。

script.php?userid=222 
script.php?userid=523 
script.php?userid=665 
script.php?userid=852 
script.php?userid=132 
script.php?userid=002 

は、最後の要求に応じて、エラーメッセージが表示されるはずです。ここで

は、基本的なコードです:

$id = $_GET['userid']; 
if (!isset($_GET['userid']) || empty($_GET['userid'])) { 
    echo "Please enter the userid"; 
    die(); 
} 

if (file_exists($userid.".txt") && 
     (filemtime($userid.".txt") > (time() - 3600 * $ttime))) { 
    $ffile = file_get_contents($userid.".txt");} else { 
    $dcurl = curl_init(); 
    $ffile = fopen($userid.".txt", "w+"); 
    curl_setopt($dcurl, CURLOPT_URL,"http://remoteserver.com/data/$userid"); 
    curl_setopt($dcurl, CURLOPT_RETURNTRANSFER, TRUE); 
    curl_setopt($dcurl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); 
    curl_setopt($dcurl, CURLOPT_TIMEOUT, 50); 
    curl_setopt($dcurl, CURLOPT_FILE, $ffile); 
    $ffile = curl_exec($dcurl); 
    if(curl_errno($dcurl)) // check for execution errors 
    { 
     echo 'Script error: ' . curl_error($dcurl); 
     exit; 
    } 
    curl_close($dcurl); 
    $ffile = file_get_contents($userid.".txt"); 
} 
+0

最も信頼できる方法は、どこかのIPアドレスを保存することですか:あなたはユーザーID引数の有無をチェックして、ファイルの内容を検索する前に、右後にそれを配置する必要がありますデータベース)と、アクセスされたファイルIDおよび日時フィールドとを含んでいる。しかし、これはかなりのサーバートラフィックを生成し、多くのユーザーがいる場合はmysqlサーバーに負荷がかかるでしょう。タイムアウトのあるクッキーやセッションは、リソースが大幅に少なくなります。しかし、彼らはまた、簡単に回避することができます。 (クッキーを削除するかブラウザを閉じてセッションを破棄する)。まず、信頼性とスケーラビリティのどちらかを選択する必要があります。 – icecub

+0

最近ではIPアドレスを本当に信頼できないので、ここでは最も信頼性が高いと言っています。 * Tor *のようなブラウザは、ボタンを押すだけで5秒以内に新しいIPアドレスを与えることができます。だから私はそれが本当にトラブルの価値があるかどうかを調べるだろうか? – icecub

答えて

7

代わりのIPアドレスに依存する、あなたは、セッション・メカニズムを使用することができます。 session_start()を介してセッションスコープを作成し、同じユーザーセッションを保持する情報を格納することができます。

このセッションスコープには、ユーザーが以前に行った要求で使用された一意のIDのリストと、要求の時間とともに、常に許可されている繰り返し要求は無視されます。このリストに5つの要素があり、直前のタイムスタンプで新しいIDが要求されると、エラーを表示してルックアップを拒否します。

これは、これを行うコードです。ファイルのように(

// set the variables that define the limits: 
$min_time = 60; // seconds 
$max_requests = 5; 

// Make sure we have a session scope 
session_start(); 

// Create our requests array in session scope if it does not yet exist 
if (!isset($_SESSION['requests'])) { 
    $_SESSION['requests'] = array(); 
} 

// Create a shortcut variable for this array (just for shorter & faster code) 
$requests = &$_SESSION['requests']; 

$countRecent = 0; 
$repeat = false; 
foreach($requests as $request) { 
    // See if the current request was made before 
    if ($request["userid"] == $id) { 
     $repeat = true; 
    } 
    // Count (only) new requests made in last minute 
    if ($request["time"] >= time() - $min_time) { 
     $countRecent++; 
    } 
} 

// Only if this is a new request... 
if (!$repeat) { 
    // Check if limit is crossed. 
    // NB: Refused requests are not added to the log. 
    if ($countRecent >= $max_requests) { 
     die("Too many new ID requests in a short time"); 
    } 
    // Add current request to the log. 
    $countRecent++; 
    $requests[] = array("time" => time(), "userid" => $id); 
} 

// Debugging code, can be removed later: 
echo count($requests) . " unique ID requests, of which $countRecent in last minute.<br>"; 

// if execution gets here, then proceed with file content lookup as you have it. 
+0

ありがとう、驚くほど魅力的な作品です!あなたはマスターです、あなたは私の問題を解決します!ハッピーニューイヤーとメリークリスマス。 – smallbee

+0

ようこそ。明けましておめでとうございます! – trincot

関連する問題