How to limit the number of user requests made per minute

The user will request the file by number via the URL, for example script.php?userid=222 . In this example, file entry # 222 will be shown.

Now I want to limit the number of files per user (remote IP) to 5 different records per minute. However, the user must be able to access the same id record for any amount of time.

Thus, the user can access file # 222 any number of times, but if the user (remote IP) accesses more than 5 other entries in a minute, then he should show an error.

For example, suppose the following requests are made within a minute:

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

then at the last request it should show an error message.

Here is the basic code:

 $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"); } 
+5
source share
1 answer

Instead of relying on an IP address, you can use a session mechanism. You can create a session scope using session_start() , and then save the information that is stored in the same user session.

Then I propose to keep in this session area a list of unique identifiers used in previous requests that the user made along with the request time, ignoring any repeated requests that are always allowed. As soon as this list contains 5 items with a time stamp in the last minute and a new identifier is requested, you display an error and refuse to search.

Here is the code that does this. You should put it right after you check the userid argument and before receiving the contents of the file:

 // 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. 
+8
source

Source: https://habr.com/ru/post/1239265/


All Articles