本文目录导读:

针对PHP项目的反欺诈与黑名单机制,我为您提供一个完整的实现方案,这个系统包含IP、设备、用户等多维度检测。
核心数据表设计
-- 黑名单表
CREATE TABLE blacklist (
id INT AUTO_INCREMENT PRIMARY KEY,
type ENUM('ip', 'user_id', 'device_id', 'phone', 'email', 'card') NOT NULL,
value VARCHAR(255) NOT NULL,
reason VARCHAR(500),
level TINYINT DEFAULT 1, -- 1-5, 5为最高风险
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
expires_at TIMESTAMP NULL,
status TINYINT DEFAULT 1, -- 1有效, 0禁用
UNIQUE KEY uk_type_value (type, value),
INDEX idx_type_status (type, status),
INDEX idx_value (value),
INDEX idx_expires (expires_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 行为日志表
CREATE TABLE behavior_log (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
user_id INT,
ip VARCHAR(45),
device_fingerprint VARCHAR(255),
action VARCHAR(100),
action_params TEXT,
risk_score DECIMAL(5,2) DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_user_action (user_id, action),
INDEX idx_ip (ip),
INDEX idx_device (device_fingerprint),
INDEX idx_created (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 风控规则表
CREATE TABLE risk_rules (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
rule_type VARCHAR(50),
conditions JSON, -- 规则条件
action VARCHAR(50), -- deny, review, allow
weight DECIMAL(5,2) DEFAULT 1,
status TINYINT DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
核心反欺诈类
<?php
namespace App\Security;
class AntiFraudManager
{
private $db;
private $cache;
private $config;
public function __construct(\PDO $db, $cache = null, array $config = [])
{
$this->db = $db;
$this->cache = $cache;
$this->config = array_merge([
'max_login_attempts' => 5,
'login_window' => 300,
'max_register_per_ip' => 3,
'register_window' => 3600,
'risk_threshold' => 0.7
], $config);
}
/**
* 检查请求是否安全
*/
public function checkRequest(RequestContext $context): RiskResult
{
$totalRisk = 0;
$reasons = [];
// 1. 黑名单检查
$blacklistCheck = $this->checkBlacklist($context);
if ($blacklistCheck->isBlocked()) {
return new RiskResult(true, $blacklistCheck->getReasons(), 1.0);
}
// 2. 行为分析
$behaviorRisk = $this->analyzeBehavior($context);
$totalRisk += $behaviorRisk['score'];
$reasons = array_merge($reasons, $behaviorRisk['reasons']);
// 3. 设备指纹检查
$deviceRisk = $this->analyzeDevice($context);
$totalRisk += $deviceRisk['score'];
$reasons = array_merge($reasons, $deviceRisk['reasons']);
// 4. 规则引擎
$ruleResults = $this->applyRules($context);
$totalRisk += $ruleResults['score'];
$reasons = array_merge($reasons, $ruleResults['reasons']);
$finalRisk = min($totalRisk, 1.0);
$isBlocked = $finalRisk >= $this->config['risk_threshold'];
// 记录行为日志
$this->logBehavior($context, $finalRisk);
return new RiskResult($isBlocked, $reasons, $finalRisk);
}
/**
* 黑名单检查
*/
private function checkBlacklist(RequestContext $context): RiskResult
{
$checks = [
['type' => 'ip', 'value' => $context->ip],
['type' => 'user_id', 'value' => $context->userId],
['type' => 'device_id', 'value' => $context->deviceId],
['type' => 'phone', 'value' => $context->phone],
['type' => 'email', 'value' => $context->email]
];
$reasons = [];
foreach ($checks as $check) {
if (empty($check['value'])) continue;
$stmt = $this->db->prepare(
"SELECT reason, level FROM blacklist
WHERE type = ? AND value = ? AND status = 1
AND (expires_at IS NULL OR expires_at > NOW())"
);
$stmt->execute([$check['type'], $check['value']]);
if ($row = $stmt->fetch()) {
$reasons[] = "Blacklisted {$check['type']}: {$row['reason']}";
return new RiskResult(true, $reasons, $row['level'] / 5);
}
}
return new RiskResult(false, [], 0);
}
/**
* 行为分析
*/
private function analyzeBehavior(RequestContext $context): array
{
$score = 0;
$reasons = [];
// 检查登录频率
if ($context->action === 'login') {
$attempts = $this->getLoginAttempts($context->ip, $this->config['login_window']);
if ($attempts >= $this->config['max_login_attempts']) {
$score += 0.4;
$reasons[] = "Excessive login attempts: {$attempts}";
}
}
// 检查注册频率
if ($context->action === 'register') {
$registrations = $this->getRegistrationsByIP($context->ip, $this->config['register_window']);
if ($registrations >= $this->config['max_register_per_ip']) {
$score += 0.5;
$reasons[] = "Excessive registrations from same IP";
}
}
// 检查异常时间段
$hour = date('H');
if ($hour >= 1 && $hour <= 5) {
$score += 0.1;
}
return ['score' => min($score, 1.0), 'reasons' => $reasons];
}
/**
* 设备分析
*/
private function analyzeDevice(RequestContext $context): array
{
$score = 0;
$reasons = [];
if (empty($context->deviceFingerprint)) {
return ['score' => 0.1, 'reasons' => ['No device fingerprint']];
}
// 检查设备关联风险用户
$stmt = $this->db->prepare(
"SELECT COUNT(*) as cnt FROM behavior_log
WHERE device_fingerprint = ?
AND risk_score > 0.5
AND created_at > DATE_SUB(NOW(), INTERVAL 24 HOUR)"
);
$stmt->execute([$context->deviceFingerprint]);
$result = $stmt->fetch();
if ($result['cnt'] > 3) {
$score += 0.3;
$reasons[] = "Device associated with risk activities";
}
return ['score' => min($score, 1.0), 'reasons' => $reasons];
}
/**
* 规则引擎
*/
private function applyRules(RequestContext $context): array
{
$totalScore = 0;
$reasons = [];
$stmt = $this->db->query("SELECT * FROM risk_rules WHERE status = 1");
$rules = $stmt->fetchAll();
foreach ($rules as $rule) {
$conditions = json_decode($rule['conditions'], true);
$matched = $this->evaluateConditions($conditions, $context);
if ($matched) {
$totalScore += $rule['weight'] * 0.1;
$reasons[] = "Rule matched: {$rule['name']}";
if ($rule['action'] === 'deny') {
$totalScore = 1.0;
break;
}
}
}
return ['score' => min($totalScore, 1.0), 'reasons' => $reasons];
}
/**
* 添加黑名单
*/
public function addToBlacklist(string $type, string $value, string $reason,
int $level = 3, ?int $expiresInHours = null): bool
{
$expiresAt = $expiresInHours ? date('Y-m-d H:i:s', time() + $expiresInHours * 3600) : null;
try {
$stmt = $this->db->prepare(
"INSERT INTO blacklist (type, value, reason, level, expires_at)
VALUES (?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE reason = VALUES(reason), level = VALUES(level),
expires_at = VALUES(expires_at), status = 1"
);
return $stmt->execute([$type, $value, $reason, $level, $expiresAt]);
} catch (\Exception $e) {
// 记录日志
return false;
}
}
/**
* 获取登录尝试次数
*/
private function getLoginAttempts(string $ip, int $window): int
{
$key = "login_attempts:{$ip}";
if ($this->cache) {
return (int)$this->cache->get($key, 0);
}
$stmt = $this->db->prepare(
"SELECT COUNT(*) FROM behavior_log
WHERE ip = ? AND action = 'login'
AND created_at > DATE_SUB(NOW(), INTERVAL ? SECOND)"
);
$stmt->execute([$ip, $window]);
return (int)$stmt->fetchColumn();
}
}
请求上下文类
<?php
namespace App\Security;
class RequestContext
{
public $ip;
public $userId;
public $deviceId;
public $deviceFingerprint;
public $phone;
public $email;
public $action;
public $userAgent;
public $referer;
public $timestamp;
public function __construct(array $data = [])
{
$this->ip = $data['ip'] ?? $_SERVER['REMOTE_ADDR'] ?? '';
$this->userId = $data['user_id'] ?? null;
$this->deviceId = $data['device_id'] ?? null;
$this->deviceFingerprint = $data['fingerprint'] ?? '';
$this->phone = $data['phone'] ?? '';
$this->email = $data['email'] ?? '';
$this->action = $data['action'] ?? '';
$this->userAgent = $data['user_agent'] ?? $_SERVER['HTTP_USER_AGENT'] ?? '';
$this->referer = $data['referer'] ?? $_SERVER['HTTP_REFERER'] ?? '';
$this->timestamp = $data['timestamp'] ?? time();
}
}
风险结果类
<?php
namespace App\Security;
class RiskResult
{
private $isBlocked;
private $reasons;
private $riskScore;
public function __construct(bool $isBlocked, array $reasons = [], float $riskScore = 0)
{
$this->isBlocked = $isBlocked;
$this->reasons = $reasons;
$this->riskScore = $riskScore;
}
public function isBlocked(): bool
{
return $this->isBlocked;
}
public function getReasons(): array
{
return $this->reasons;
}
public function getRiskScore(): float
{
return $this->riskScore;
}
public function getHttpCode(): int
{
return $this->isBlocked ? 403 : 200;
}
public function toArray(): array
{
return [
'blocked' => $this->isBlocked,
'risk_score' => $this->riskScore,
'reasons' => $this->reasons
];
}
}
中间件使用示例
<?php
namespace App\Middleware;
use App\Security\AntiFraudManager;
use App\Security\RequestContext;
class AntiFraudMiddleware
{
private $fraudManager;
public function __construct(AntiFraudManager $fraudManager)
{
$this->fraudManager = $fraudManager;
}
public function handle($request, $next)
{
// 创建请求上下文
$context = new RequestContext([
'action' => $request->getPath(),
'user_id' => $request->getUserId(),
'device_id' => $request->header('X-Device-ID'),
'fingerprint' => $this->getDeviceFingerprint($request),
'phone' => $request->input('phone'),
'email' => $request->input('email')
]);
// 风控检查
$result = $this->fraudManager->checkRequest($context);
if ($result->isBlocked()) {
return response()->json([
'error' => 'Request blocked',
'reasons' => $result->getReasons(),
'code' => $result->getHttpCode()
], $result->getHttpCode());
}
// 将风险信息注入请求
$request->attributes->set('risk_score', $result->getRiskScore());
return $next($request);
}
private function getDeviceFingerprint($request): string
{
// 使用多个参数生成设备指纹
$components = [
$request->header('User-Agent'),
$request->header('Accept-Language'),
$request->header('Accept-Encoding'),
$request->ip()
];
return md5(implode('|', $components));
}
}
自动清理脚本
<?php
// cron_jobs/cleanup_blacklist.php
// 建议每天运行一次
$stmt = $db->prepare(
"DELETE FROM blacklist WHERE expires_at IS NOT NULL AND expires_at < NOW()"
);
$stmt->execute();
// 清理过期行为日志(保留最近30天)
$stmt = $db->prepare(
"DELETE FROM behavior_log WHERE created_at < DATE_SUB(NOW(), INTERVAL 30 DAY)"
);
$stmt->execute();
配置建议
// config/antifraud.php
return [
'redis' => [
'host' => '127.0.0.1',
'port' => 6379,
'prefix' => 'antifraud:'
],
'rate_limits' => [
'login' => [
'max_attempts' => 5,
'window' => 300 // 5分钟
],
'register' => [
'max_attempts' => 3,
'window' => 3600 // 1小时
],
'api' => [
'max_requests' => 100,
'window' => 60 // 1分钟
]
],
'blacklist' => [
'auto_ban_threshold' => 0.8, // 触发自动加入黑名单的风险分数
'auto_ban_duration' => 24 // 自动封禁小时数
],
'notifications' => [
'high_risk_alert' => true,
'alert_channels' => ['email', 'sms'],
'alert_recipients' => ['admin@example.com']
]
];
这个系统提供了完整的反欺诈功能,包括:
- 多维黑名单:支持IP、用户、设备、手机、邮箱等多个维度
- 行为分析:检测异常登录、注册频率等
- 设备指纹:识别设备关联风险
- 规则引擎:可配置的风控规则
- 自动封禁:达到风险阈值自动加入黑名单
- 缓存优化:支持Redis缓存提高性能
- 可扩展性:易于添加新的检测规则
建议配合Nginx限流、验证码、实名认证等机制一起使用,构建完整的防护体系。
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播