gpt4 book ai didi

php - 提供基于 IP 的冷却期的可移植方式?

转载 作者:行者123 更新时间:2023-11-29 22:16:58 27 4
gpt4 key购买 nike

我有一个在网络服务器上运行的 PHP API 前端。这个特定的 PHP 程序是要分发的,因此它应该尽可能可移植。

我想要实现的功能是IP冷却期,这意味着同一个IP每秒最多只能请求API两次,意味着至少有500ms的延迟。

我想到的方法是将 IP 与最新请求时间戳一起存储在 MySQL 数据库中。我通过以下方式获取IP:

if (getenv('REMOTE_ADDR'))
$ipaddress = getenv('REMOTE_ADDR');

但某些服务器可能没有 MySQL 数据库,或者安装此数据库的用户无权访问。另一个问题是数据库的清理。

是否有更便携的方式来临时存储 IP(记住 IPv6)?

如何自动清理早于 500 毫秒的 IP,同时将性能影响降至最低?

另外:我对查看存储的 IP 不感兴趣,这只是关于延迟。

最佳答案

这就是我现在使用文件解决这个问题的方法。

程序

  1. 获取客户端 IP 并对其进行哈希处理(以防止文件读出)。
  2. 打开 IP 文件并扫描每一行
  3. 将当前记录的时间与当前时间进行比较
  4. 如果差值大于设置的超时,则转到 5,否则转到 7。
  5. 如果 IP 与客户端匹配,则创建更新记录,否则
  6. 删除记录。
  7. 如果IP与客户端匹配,则提供失败消息,否则复制记录。

示例代码

<?php

$sIPHash = md5($_SERVER[REMOTE_ADDR]);
$iSecDelay = 10;
$sPath = "bucket.cache";
$bReqAllow = false;
$iWait = -1;
$sContent = "";

if ($nFileHandle = fopen($sPath, "c+")) {
flock($nFileHandle, LOCK_EX);
$iCurLine = 0;
while (($sCurLine = fgets($nFileHandle, 4096)) !== FALSE) {
$iCurLine++;
$bIsIPRec = strpos($sCurLine, $sIPHash);
$iLastReq = strtok($sCurLine, '|');
// this record expired anyway:
if ( (time() - $iLastReq) > $iSecDelay ) {
// is it also our IP?
if ($bIsIPRec !== FALSE) {
$sContent .= time()."|".$sIPHash.PHP_EOL;
$bReqAllow = true;
}
} else {
if ($bIsIPRec !== FALSE) $iWait = ($iSecDelay-(time()-$iLastReq));
$sContent .= $sCurLine.PHP_EOL;
}
}
}

if ($iWait == -1 && $bReqAllow == false) {
// no record yet, create one
$sContent .= time()."|".$sIPHash.PHP_EOL;
echo "Request from new user successful!";
} elseif ($bReqAllow == true) {
echo "Request from old user successful!";
} else {
echo "Request failed! Wait " . $iWait . " seconds!";
}

ftruncate($nFileHandle, 0);
rewind($nFileHandle);
fwrite($nFileHandle, $sContent);
flock($nFileHandle, LOCK_UN);
fclose($nFileHandle);
?>

备注

新用户

如果 IP 哈希与任何记录都不匹配,则会创建一条新记录。注意:如果您没有权限,访问可能会失败。

内存

如果您预计流量很大,请切换到数据库解决方案,例如 this全部在一起。

冗余代码

“但是 minxomat”,您可能会说,“现在每个客户端都会循环访问整个文件!”。是的,确实如此,这就是我想要的解决方案。这样,每个客户端都有责任清理整个文件。即便如此,对性能的影响仍然很低,因为如果每个客户端都进行清理,文件大小将保持在绝对最小值。如果这种方式不适合您,请更改此设置。

关于php - 提供基于 IP 的冷却期的可移植方式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31138984/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com