本文目录导读:

设计一个完善的PHP防刷机制需要从多个层面考虑,这里提供一个全面的防刷设计方案:
基础防刷层(请求频率控制)
IP限流中间件
<?php
class RateLimiter {
private $redis;
private $maxRequests;
private $timeWindow;
public function __construct($redis, $maxRequests = 60, $timeWindow = 60) {
$this->redis = $redis;
$this->maxRequests = $maxRequests;
$this->timeWindow = $timeWindow;
}
/**
* 滑动窗口限流
*/
public function limitByIP($ip) {
$key = "rate_limit:ip:{$ip}:" . time();
$count = $this->redis->incr($key);
if ($count === 1) {
$this->redis->expire($key, $this->timeWindow);
}
if ($count > $this->maxRequests) {
throw new \Exception("请求过于频繁", 429);
}
return true;
}
/**
* 令牌桶算法
*/
public function tokenBucket($ip, $capacity = 100, $refillRate = 10) {
$bucketKey = "bucket:{$ip}";
$tokenKey = "tokens:{$ip}";
$lastRefillKey = "last_refill:{$ip}";
$currentTokens = (float)$this->redis->get($tokenKey);
$lastRefill = (int)$this->redis->get($lastRefillKey);
if ($currentTokens === false) {
$currentTokens = $capacity;
$lastRefill = time();
}
// 计算应补充的令牌
$elapsed = time() - $lastRefill;
$newTokens = min($capacity, $currentTokens + ($elapsed * $refillRate));
$this->redis->multi()
->set($tokenKey, $newTokens)
->set($lastRefillKey, time())
->exec();
if ($newTokens < 1) {
throw new \Exception("请求过于频繁,请稍后再试", 429);
}
return true;
}
}
用户级别防刷
用户行为监控
<?php
class UserAntiSpam {
private $db;
private $redis;
/**
* 用户操作频率控制
*/
public function checkUserAction($userId, $action, $limit = 10, $window = 3600) {
$key = "user:{$userId}:action:{$action}:" . date('Y-m-d-H-i');
// 使用计数器
$count = $this->redis->incr($key);
if ($count === 1) {
$this->redis->expire($key, $window);
}
if ($count > $limit) {
$this->logViolation($userId, $action, 'frequency_exceeded');
return false;
}
return true;
}
/**
* 黑名单机制
*/
public function addToBlacklist($userId, $reason, $duration = 86400) {
$key = "blacklist:user:{$userId}";
$this->redis->setex($key, $duration, json_encode([
'reason' => $reason,
'time' => time()
]));
// 记录到数据库
$this->db->insert('user_blacklist', [
'user_id' => $userId,
'reason' => $reason,
'duration' => $duration
]);
}
/**
* 检查是否在黑名单
*/
public function isBlacklisted($userId) {
$key = "blacklist:user:{$userId}";
return $this->redis->exists($key);
}
}
验证码机制
多重验证码系统
<?php
class CaptchaSystem {
private $redis;
/**
* 生成图片验证码
*/
public function generateImageCaptcha($sessionId) {
$captcha = $this->generateRandomCode(4);
$key = "captcha:{$sessionId}";
// 存储验证码和过期时间
$this->redis->setex($key, 300, $captcha);
// 生成图片
$image = imagecreatetruecolor(120, 40);
// ... 图片绘制代码
return $image;
}
/**
* 行为验证码(点击验证,需要前端配合)
*/
public function verifyBehavior($userId, $behaviorData) {
// 记录用户行为特征
$key = "user:{$userId}:behavior";
$features = [
'mouse_speed' => $behaviorData['mouse_speed'],
'click_delay' => $behaviorData['click_delay'],
'move_pattern' => $behaviorData['move_pattern']
];
// 分析是否是机器人操作
$riskScore = $this->calculateRiskScore($features);
return $riskScore < 0.5; // 分数低于0.5判定为正常
}
/**
* 滑动验证码(需要前端配合)
*/
public function verifySliderCaptcha($sessionId, $sliderData) {
// 记录滑动轨迹时长
$startTime = $this->redis->get("slider:{$sessionId}:start");
$endTime = time() * 1000;
$duration = $endTime - $startTime;
// 人类滑动通常需要1-3秒
if ($duration < 500 || $duration > 5000) {
return false;
}
// 验证滑动轨迹
return true;
}
}
业务逻辑防刷
业务层防刷规则
<?php
class BusinessAntiSpam {
private $db;
private $redis;
/**
* 注册防刷
*/
public function checkRegistration($ip, $phone, $deviceId) {
// IP注册数量限制
$ipKey = "register:ip:{$ip}:" . date('Y-m-d');
$ipCount = $this->redis->incr($ipKey);
if ($ipCount > 5) {
return false; // 单个IP每天最多注册5次
}
// 手机号重复注册检查
$phoneExists = $this->db->query(
"SELECT COUNT(*) FROM users WHERE phone = ?",
[$phone]
)->fetchColumn();
if ($phoneExists > 0) {
return false;
}
// 设备指纹检查
$deviceKey = "register:device:{$deviceId}:" . date('Y-m-d');
$deviceCount = $this->redis->incr($deviceKey);
if ($deviceCount > 3) {
return false; // 单个设备每天最多注册3次
}
return true;
}
/**
* 登录防刷
*/
public function checkLogin($userId, $password, $ip) {
// 密码错误次数限制
$failKey = "login:fail:{$userId}:" . date('Y-m-d-H');
$failCount = $this->redis->incr($failKey);
if ($failCount > 5) {
$this->temporaryLockUser($userId, 30); // 锁定30分钟
return false;
}
// IP异常检测
$ipKey = "login:ip:{$ip}:unusual";
$normalIps = $this->db->query(
"SELECT COUNT(*) FROM login_logs WHERE user_id = ? AND ip = ?",
[$userId, $ip]
)->fetchColumn();
if ($normalIps == 0 && $failCount > 3) {
// 新IP登录且多次失败
return false;
}
return true;
}
/**
* 短信验证码防刷
*/
public function checkSmsCode($phone, $type) {
// 发送频率限制(60秒内只能发1条)
$sendKey = "sms:send:{$phone}:{$type}";
$lastSend = $this->redis->get($sendKey);
if ($lastSend && (time() - $lastSend) < 60) {
return false;
}
// 每天数量限制
$dailyKey = "sms:daily:{$phone}:{$type}:" . date('Y-m-d');
$dailyCount = $this->redis->incr($dailyKey);
if ($dailyCount > 10) {
return false;
}
// 验证码错误次数限制
$verifyKey = "sms:verify:{$phone}:{$type}:fail";
$failCount = $this->redis->incr($verifyKey);
if ($failCount > 5) {
return false;
}
return true;
}
}
全局防护配置
完整的防刷系统配置
<?php
class AntiSpamConfig {
// 防刷策略配置
private static $config = [
'rate_limits' => [
'api' => ['limit' => 60, 'window' => 60], // API 60次/分钟
'login' => ['limit' => 10, 'window' => 60], // 登录 10次/分钟
'register' => ['limit' => 5, 'window' => 3600], // 注册 5次/小时
'sms_send' => ['limit' => 3, 'window' => 3600], // 短信发送 3次/小时
],
'blacklist' => [
'ip_blacklist' => [], // IP黑名单
'user_blacklist' => [], // 用户黑名单
'device_blacklist' => [] // 设备黑名单
],
'behavior' => [
'max_errors' => 5, // 最大错误次数
'lock_duration' => 30, // 锁定时间(分钟)
'captcha_threshold' => 3 // 触发验证码的阈值
]
];
/**
* 全局安全检查
*/
public static function globalCheck($request) {
// 检查IP是否被禁止
$ip = $request->getClientIp();
if (self::isIPBlacklisted($ip)) {
return false;
}
// 检查用户Agent
$userAgent = $request->getUserAgent();
if (self::isSuspiciousUserAgent($userAgent)) {
return false;
}
// 检查请求头
$headers = $request->getHeaders();
if (self::hasAbnormalHeaders($headers)) {
return false;
}
// 响应头添加反爬标记
$response = new Response();
$response->headers->set('X-Robots-Tag', 'noindex, nofollow');
return true;
}
}
// 使用示例
class ExampleController {
public function sensitiveAction(Request $request) {
// 执行防刷检查
if (!AntiSpamConfig::globalCheck($request)) {
return response()->json(['error' => '访问被拒绝'], 403);
}
// 业务逻辑...
}
}
监控与日志
防刷监控系统
<?php
class AntiSpamMonitor {
private $db;
private $elasticsearch;
/**
* 实时监控
*/
public function monitor() {
// 实时流量监控
$currentQPS = $this->getCurrentQPS();
$threshold = 1000;
if ($currentQPS > $threshold) {
$this->triggerAlert("高流量警告", $currentQPS);
}
// 异常检测
$anomalies = $this->detectAnomalies();
foreach ($anomalies as $anomaly) {
$this->handleAnomaly($anomaly);
}
}
/**
* 日志记录
*/
public function logAntiSpamEvent($ip, $event, $details) {
$logEntry = [
'timestamp' => date('Y-m-d H:i:s'),
'ip' => $ip,
'event' => $event,
'details' => json_encode($details)
];
// 记录到数据库
$this->db->insert('security_logs', $logEntry);
// 记录到Elasticsearch用于分析
$this->elasticsearch->index('antispam_events', $logEntry);
}
}
最佳实践建议
使用中间件组合
// 在Laravel或ThinkPHP中注册中间件
protected $middleware = [
GlobalRateLimit::class, // 全局限流
IPWhitelist::class, // IP白名单
SecurityHeaders::class, // 安全头
UserAuthCheck::class, // 用户认证
RequestValidation::class, // 请求验证
];
// 路由分组
Route::group(['middleware' => ['rate_limit:login']], function () {
Route::post('/login', 'AuthController@login');
});
动态调整策略
class AdaptiveAntiSpam {
public function adjustStrategy($userId, $riskLevel) {
switch ($riskLevel) {
case 'low':
$this->setRateLimit($userId, 100, 60);
break;
case 'medium':
$this->setRateLimit($userId, 20, 60);
$this->requireCaptcha(true);
break;
case 'high':
$this->setRateLimit($userId, 5, 3600);
$this->lockAccount($userId);
break;
}
}
}
注意事项
- 性能优化:使用Redis等缓存工具存储计数数据,避免频繁数据库操作
- 误杀处理:设计合理的惩罚机制,避免误杀正常用户
- 分布式支持:在集群环境中,使用Redis共享计数状态
- API设计:提供友好的错误信息,便于前端展示
- 安全更新:定期评估和更新防刷策略
这个防刷系统设计涵盖了多个层面,可以根据实际业务需求进行裁剪和扩展,记得要持续监控效果并定期优化策略。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播