如何限制一分钟内发出的用户请求数

小蜜蜂

用户将通过URL通过数字请求文件script.php?userid=222本示例将显示文件#222的记录。

现在,我想将每(远程IP)用户的文件数量限制为一分钟内最多5个不同的记录。但是,用户应该能够多次访问相同的ID记录。

因此,用户可以多次访问文件222,但是,如果(远程IP)用户在一分钟内访问了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");
}
亭子

您可以使用会话机制来代替IP地址。您可以通过创建会话范围session_start(),然后存储与同一用户会话相关的信息。

然后,我建议在此会话范围内保留用户先前发出的请求中使用的唯一ID的列表以及请求的时间,而忽略任何重复的请求(始终允许)。一旦此列表在最后一分钟内包含5个带有时间戳的元素,并且请求了新的ID,您就会显示错误并拒绝查找。

这是执行此操作的代码。在检查了userid参数的存在之后以及在检索文件内容之前,应立即将其放置

// 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'] = [];
}

// 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[] = ["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.

删除的会话Cookie ...

会话由客户端上的cookie维护。用户可以删除此类cookie,从而获得一个新会话,这将允许用户发出新请求而无需考虑先前的请求。

解决此问题的一种方法是为每个新会话引入一个冷静期。例如,您可以让他们等待10秒钟,然后才能发出第一个请求。为此,请替换上面的代码:

if (!isset($_SESSION['requests'])) {
    $_SESSION['requests'] = [];
}

经过:

$initial_delay = 10; // 10 seconds delay for new sessions
if (!isset($_SESSION['requests'])) {
    $_SESSION['requests'] = array_fill(0, $max_requests,
        ["userid" => 0, "time" => time()-$min_time+$initial_delay] 
    );
}

当然,这会降低用户友好度,因为它会影响任何新会话,也会影响那些不试图通过删除cookie来作弊的用户。

登记

更好的方法是仅将查找服务提供给注册用户。为此,您必须提供用户数据库和身份验证系统(例如,基于密码)。这些请求应记录在数据库中,并以用户的ID键输入。如果然后开始新的会话,则用户必须首先再次进行身份验证,并且一旦身份验证,就从数据库中检索请求历史记录。这样,用户无法通过更改客户端配置上的某些内容(IP地址,cookie,并行使用多个设备等)来作弊。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

每隔一分钟通过Node.js发出一个请求

来自分类Dev

如何在执行另一分钟后的x分钟内执行SQL查询?

来自分类Dev

使用JMeter找出服务器在一分钟内是否可以处理100个用户

来自分类Dev

uwsgi 无法处理超过一分钟的请求

来自分类Dev

从最后一分钟开始活动(PHP)

来自分类Dev

给字符串加一分钟

来自分类Dev

DateTime.TryParseExact增加一分钟?

来自分类Dev

DateTime.TryParseExact增加一分钟?

来自分类Dev

一分钟。字典中的值

来自分类Dev

一分钟后无法上网

来自分类Dev

运行Cron不到一分钟-Laravel

来自分类Dev

WordPress网站加载将近一分钟

来自分类Dev

Ubuntu 需要一分钟才能启动

来自分类Dev

Javascript-提交后一分钟内无法提交的表单

来自分类Dev

Robocopy可以在少于一分钟的时间增量内监视文件吗?

来自分类Dev

一分钟内Google Chrome细分错误

来自分类Dev

Outlook:标记的电子邮件在一分钟内过期,变红

来自分类Dev

优化:如何从一周的每一分钟的时间获取TimeId?

来自分类Dev

如何将一分钟的cron延迟一个小时

来自分类Dev

如何在XTS中索引一分钟的盘中数据?

来自分类Dev

如何在matplotlib中删除一分钟的轴标签

来自分类Dev

如何每隔一分钟从网络摄像头拍照?

来自分类Dev

如何替换事件页面扩展中的短(不到一分钟)setTimeouts

来自分类Dev

FFMPEG:如何保持UDP流连接打开甚至源掉一分钟

来自分类Dev

我如何每隔一分钟在php中执行代码?

来自分类Dev

重启一分钟后如何执行系统命令(Linux)?

来自分类Dev

如何在安装新的crontab时修复“糟糕的一分钟”错误

来自分类Dev

如何知道每隔一分钟重新启动哪个服务

来自分类Dev

如何每隔一分钟将2加到当前值?

Related 相关文章

热门标签

归档