Files
CLOAK/lib/Cloak/RiskSecondaryCache.php
T
2026-06-15 22:42:59 +08:00

109 lines
3.4 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
require_once __DIR__ . '/ClientIpResolver.php';
require_once __DIR__ . '/FpUrlHelper.php';
/**
* 二次风控(byApiRiskSession 缓存:同 Session 内复用判定结果,IP 变化时失效。
*/
class RiskSecondaryCache
{
const SESSION_KEY = 'cloak_risk_cache';
/**
* @param array{result:string,reason?:string,fp_url?:string,ip?:string} $payload
*/
public static function store(array $payload)
{
$ip = ClientIpResolver::normalizeIp($payload['ip'] ?? ClientIpResolver::resolve());
if ($ip === null) {
return;
}
$_SESSION[self::SESSION_KEY] = [
'ip' => $ip,
'result' => ($payload['result'] ?? '') === 'true' ? 'true' : 'false',
'reason' => (string) ($payload['reason'] ?? ''),
'fp_url' => (string) ($payload['fp_url'] ?? ''),
'risk_number' => defined('CLOAK_RISK_NUMBER') ? (int) CLOAK_RISK_NUMBER : 0,
'campaign_id' => defined('COSTM_IP_SCORE') ? (string) COSTM_IP_SCORE : '',
'cached_at' => time(),
];
}
/**
* @param string|null $currentIp 为空时使用 ClientIpResolver::resolve()
* @return array|null
*/
public static function get($currentIp = null)
{
if (empty($_SESSION[self::SESSION_KEY]) || !is_array($_SESSION[self::SESSION_KEY])) {
return null;
}
$cached = $_SESSION[self::SESSION_KEY];
$ip = ClientIpResolver::normalizeIp($currentIp !== null && $currentIp !== '' ? $currentIp : ClientIpResolver::resolve());
$cachedIp = ClientIpResolver::normalizeIp($cached['ip'] ?? '');
$invalidate = false;
if ($ip === null || $cachedIp === null || $ip !== $cachedIp) {
$invalidate = true;
} elseif (defined('CLOAK_RISK_NUMBER') && (int) ($cached['risk_number'] ?? -1) !== (int) CLOAK_RISK_NUMBER) {
$invalidate = true;
} elseif (defined('COSTM_IP_SCORE') && (string) ($cached['campaign_id'] ?? '') !== (string) COSTM_IP_SCORE) {
$invalidate = true;
}
if ($invalidate) {
self::clear();
$_SESSION['visit_to_3'] = '1';
return null;
}
return $cached;
}
public static function clear()
{
unset($_SESSION[self::SESSION_KEY]);
}
/**
* 将缓存同步到 visit_to_3 / check_result,供 RouteResolver 等复用。
*
* @param array $cached
*/
public static function applyToSession(array $cached)
{
$_SESSION['visit_to_3'] = 3;
$_SESSION['check_result'] = ($cached['result'] ?? '') === 'true' ? 'true' : 'false';
}
public static function hitReason()
{
return '二次风控缓存命中';
}
/**
* @param array $cached
* @return array{result:bool,reason:string,link:string}
*/
public static function toApiResponse(array $cached)
{
$passed = ($cached['result'] ?? '') === 'true';
$link = (string) ($cached['fp_url'] ?? '');
if ($passed && $link === '') {
$link = FpUrlHelper::fallbackUrl();
}
if (!$passed && $link === '' && defined('DB_ZP')) {
$link = (string) DB_ZP;
}
return [
'result' => $passed,
'reason' => self::hitReason(),
'link' => $link,
];
}
}