This commit is contained in:
make
2025-06-02 13:41:20 +08:00
parent f47d5cc378
commit 83c3bd512c
2 changed files with 110 additions and 4 deletions

View File

@@ -16,6 +16,7 @@ use think\facade\Config;
use think\exception\HttpException;
use think\facade\View;
use think\Response;
use think\facade\Cache;
class SiteContext
{
@@ -110,6 +111,7 @@ class SiteContext
*/
public function initCfg()
{
$this->limitRequestRate();
if(config('app.default_app_type') == 'novel'){
// 全局使用的URL模板
$strPcUrlTemp = $this->DomainModel->getFomartSubject('PC_PATH_URL', '', false);
@@ -491,4 +493,110 @@ class SiteContext
fclose($Stream);
exit;
}
/**
* 限速访问
*
* @return void
*/
protected function limitRequestRate()
{
$arrVisitInfo = [
//'vil_ip' => $this->Request->ip(),
'vil_user_agent' => $this->Request->server('HTTP_USER_AGENT'),
// 'vil_url' => $this->Request->url(true),
// 'vil_method' => $this->Request->method(),
// 'vil_headers' => json_encode($this->Request->header()), // 保存所有 HTTP 头信息
// 'vil_timestamp' => date('Y-m-d H:i:s'), // 获取当前时间
// 'vil_content_type' => 'page',
// 'vil_content_id' => $this->Request->url(true),
];
// 判断是否为爬虫
$arrVisitInfo['vil_is_spider'] = $this->isSpider($arrVisitInfo['vil_user_agent']);
$strIp = $this->Request->ip();
$strKeyLimit10 = 'access:' . $strIp;
$strKeyLimit100 = 'access100:' . $strIp;
$strKeyBlacklist = 'blacklist:ips'; // 黑名单缓存键
// 检查是否在黑名单中
if (Cache::store('redis')->handler()->sIsMember($strKeyBlacklist, $strIp)) {
throw new HttpException(404, 'Too Many Requests');
// abort(403, 'Too Many Requests100 Your IP has been blocked.');
}
// 自增操作
$intRequestTotalLimit10 = Cache::store('redis')->handler()->incr($strKeyLimit10);
$intRequestTotalLimit100 = Cache::store('redis')->handler()->incr($strKeyLimit100);
// 设置过期时间(只在第一次自增时设置)
if ($intRequestTotalLimit10 === 1) {
Cache::store('redis')->handler()->expire($strKeyLimit10, 60); // 设置 1分钟 过期
Cache::store('redis')->handler()->expire($strKeyLimit100, 60 * 10); // 设置 10分钟 过期
}
var_dump($intRequestTotalLimit10);
// 检查请求次数是否超过限制
if ($intRequestTotalLimit10 > 30 && !$arrVisitInfo['vil_is_spider']) {
throw new HttpException(404, 'Too Many Requests');
// abort(403, 'Too Many Requests');
}
// 拉黑
if ($intRequestTotalLimit100 > 100 && !$arrVisitInfo['vil_is_spider']) {
// 将 IP 加入黑名单集合
Cache::store('redis')->handler()->sAdd($strKeyBlacklist, $strIp);
// 设置黑名单过期时间1 天后自动移除)
Cache::store('redis')->handler()->expire($strKeyBlacklist, 86400 * 30); // 30 天(可调整)
throw new HttpException(404, 'Too Many Requests100');
//abort(403, 'Too Many Requests100');
}
$strAGEN = 'Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Amazonbot/0.1; +https://developer.amazon.com/support/amazonbot) Chrome/119.0.6045.214 Safari/537.36';
if($arrVisitInfo['vil_user_agent'] == $strAGEN){
throw new HttpException(404, 'Too Many Requests100');
//abort(403, 'Too Many Requests100');
}
if (preg_match('/Chrome\/119\.0\.6045\.214/', $arrVisitInfo['vil_user_agent'])) {
throw new HttpException(404, 'Too Many Requests100');
//abort(403, 'Too Many Requests100');
}
}
/**
* 根据 User-Agent 识别爬虫 是否为白名单蜘蛛
*
* @param string $strUserAgent
* @return boolean
*/
protected function isSpider(string $strUserAgent)
{
# ✅ 主流搜索引擎爬虫(按需维护)
$arrSpiders = [
'Baiduspider',
'Googlebot',
'Googlebot-Mobile',
'360Spider',
'HaosouSpider',
'Sogou',
'YisouSpider',
'Bingbot',
'Quarkbot',
'YandexBot',
'Bytespider',
'ToutiaoSpider',
'YoudaoBot',
];
foreach ($arrSpiders as $strSpider) {
if (stripos($strUserAgent, $strSpider) !== false) {
return true; // 匹配到爬虫关键字
}
}
return false;
}
}