PHP风控系统与反欺诈策略
PHP风控系统与反欺诈策略
风控系统是电商和金融平台的必备组件。它检测和阻止欺诈行为,保障平台安全。今天说说PHP中构建风控系统的方法。
风控系统的核心是规则引擎和策略配置。实时风控需要在毫秒级别完成决策。
```php
class RiskRule
{
public function __construct(
public string $name,
public int $weight, // 权重
public callable $evaluate // 评估函数,返回0-100的风险分
) {}
}
class RiskResult
{
public function __construct(
public int $score,
public string $level,
public string $action,
public array $triggers = [],
public array $details = []
) {}
}
class RiskEngine
{
private array $rules = [];
private int $thresholdLow = 30;
private int $thresholdMedium = 60;
private int $thresholdHigh = 80;
public function addRule(RiskRule $rule): void
{
$this->rules[] = $rule;
}
public function evaluate(array $context): RiskResult
{
$totalScore = 0;
$totalWeight = 0;
$triggers = [];
$details = [];
foreach ($this->rules as $rule) {
try {
$score = ($rule->evaluate)($context);
$totalScore += $score * $rule->weight;
$totalWeight += $rule->weight;
if ($score > 50) {
$triggers[] = $rule->name;
}
$details[] = [
'rule' => $rule->name,
'score' => $score,
];
} catch (\Exception $e) {
continue;
}
}
$finalScore = $totalWeight > 0 ? round($totalScore / $totalWeight) : 0;
if ($finalScore >= $this->thresholdHigh) {
$level = 'high';
$action = 'block';
} elseif ($finalScore >= $this->thresholdMedium) {
$level = 'medium';
$action = 'review';
} elseif ($finalScore >= $this->thresholdLow) {
$level = 'low';
$action = 'monitor';
} else {
$level = 'safe';
$action = 'allow';
}
return new RiskResult($finalScore, $level, $action, $triggers, $details);
}
}
// 注册风控规则
$engine = new RiskEngine();
$engine->addRule(new RiskRule('异地登录检测', 30, function ($ctx) {
$userLocation = $ctx['user_location'] ?? '';
$ipLocation = $ctx['ip_location'] ?? '';
if ($userLocation && $ipLocation && $userLocation !== $ipLocation) {
return 70;
}
return 10;
}));
$engine->addRule(new RiskRule('支付频率检测', 20, function ($ctx) {
$recentPayments = $ctx['recent_payments'] ?? 0;
if ($recentPayments > 10) return 80;
if ($recentPayments > 5) return 50;
return 5;
}));
$engine->addRule(new RiskRule('新设备检测', 15, function ($ctx) {
if ($ctx['is_new_device'] ?? false) return 60;
return 5;
}));
$engine->addRule(new RiskRule('金额异常检测', 25, function ($ctx) {
$amount = $ctx['transaction_amount'] ?? 0;
$avgAmount = $ctx['user_avg_amount'] ?? 1;
$ratio = $avgAmount > 0 ? $amount / $avgAmount : 1;
if ($ratio > 10) return 90;
if ($ratio > 5) return 60;
if ($ratio > 3) return 30;
return 5;
}));
$engine->addRule(new RiskRule('IP黑名单检测', 10, function ($ctx) {
if ($ctx['ip_blacklisted'] ?? false) return 100;
return 0;
}));
// 执行风控评估
$context = [
'user_id' => 12345,
'user_location' => '北京',
'ip_location' => '上海',
'recent_payments' => 8,
'is_new_device' => true,
'transaction_amount' => 5000,
'user_avg_amount' => 300,
'ip_blacklisted' => false,
];
$result = $engine->evaluate($context);
echo "风控评分: {$result->score}\n";
echo "风险等级: {$result->level}\n";
echo "处置动作: {$result->action}\n";
echo "触发规则: " . implode(', ', $result->triggers) . "\n";
?>
>
实时风控的Redis实现:
```php
class RealTimeRiskService
{
private Redis $redis;
private int $windowSize;
public function __construct(Redis $redis, int $windowSize = 60)
{
$this->redis = $redis;
$this->windowSize = $windowSize;
}
public function checkPaymentRisk(int $userId, float $amount): array
{
$risks = [];
// 频率检测
$key = "risk:payment_freq:{$userId}";
$count = $this->redis->incr($key);
if ($count === 1) $this->redis->expire($key, $this->windowSize);
if ($count > 5) {
$risks[] = ['type' => 'high_frequency', 'count' => $count];
}
// 金额检测
$totalKey = "risk:payment_total:{$userId}";
$total = $this->redis->incrByFloat($totalKey, $amount);
if ($count === 1) $this->redis->expire($totalKey, $this->windowSize);
if ($total > 10000) {
$risks[] = ['type' => 'amount_exceed', 'total' => $total];
}
// 失败次数检测
$failKey = "risk:payment_fail:{$userId}";
$failures = (int)$this->redis->get($failKey);
if ($failures > 3) {
$risks[] = ['type' => 'too_many_failures', 'failures' => $failures];
}
return [
'has_risk' => !empty($risks),
'risks' => $risks,
'allow' => empty($risks),
];
}
public function recordPaymentResult(int $userId, bool $success): void
{
if (!$success) {
$key = "risk:payment_fail:{$userId}";
$this->redis->incr($key);
$this->redis->expire($key, 3600);
}
}
public function isIpBlacklisted(string $ip): bool
{
return (bool)$this->redis->sIsMember('risk:blacklist:ip', $ip);
}
public function addToBlacklist(string $ip): void
{
$this->redis->sAdd('risk:blacklist:ip', $ip);
$this->redis->expire('risk:blacklist:ip', 86400);
}
public function getUserRiskLevel(int $userId): string
{
$key = "risk:user_level:{$userId}";
return $this->redis->get($key) ?: 'low';
}
public function setUserRiskLevel(int $userId, string $level): void
{
$this->redis->setex("risk:user_level:{$userId}", 86400, $level);
}
}
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$riskService = new RealTimeRiskService($redis);
$check = $riskService->checkPaymentRisk(12345, 1500);
echo "支付风险检测: " . ($check['allow'] ? '允许' : '拒绝') . "\n";
foreach ($check['risks'] as $risk) {
echo " 风险: {$risk['type']}\n";
}
?>
风控系统是平台安全的最后防线。规则引擎结合实时数据检测可以阻止大多数欺诈行为。风控策略需要在安全性和用户体验之间平衡,过于严格会误伤正常用户,过于宽松又会让欺诈者有机可乘。好的风控系统通过不断迭代策略来提高准确率。
