FIX_API_RATE_LIMIT_COND

This commit is contained in:
velz 2026-02-23 18:55:38 +05:30
parent d50f49a467
commit c3d6def200
4 changed files with 83 additions and 5 deletions

View File

@ -38,7 +38,8 @@ class AuthApiRateLimitFilter implements FilterInterface
public function before(RequestInterface $request, $arguments = null)
{
$fingerprint = generateFingerprint();
$fingerprint = generateFingerprint(exclude_ua: true);
// 1. IP-level check
$ipResult = $this->limiter->checkIp($fingerprint, 'authApi');
@ -76,7 +77,8 @@ class AuthApiRateLimitFilter implements FilterInterface
return; // 2xx/3xx = success; 429/403/451 already handled
}
$fingerprint = $request->getGlobal('rateLimitFingerprint') ?? generateFingerprint();
$fingerprint = $request->getGlobal('rateLimitFingerprint') ?? generateFingerprint(exclude_ua: true);
$identity = $request->getGlobal('rateLimitIdentity')
?? $this->resolveIdentity($request);

View File

@ -39,7 +39,8 @@ class JwtApiRateLimitFilter implements FilterInterface
public function before(RequestInterface $request, $arguments = null)
{
$fingerprint = generateFingerprint();
$fingerprint = generateFingerprint(exclude_ua: true);
// 1. IP-level throttle + block check
$ipResult = $this->limiter->checkIp($fingerprint, 'jwtApi');
@ -83,7 +84,8 @@ class JwtApiRateLimitFilter implements FilterInterface
return;
}
$fingerprint = $request->getGlobal('rateLimitFingerprint') ?? generateFingerprint();
$fingerprint = $request->getGlobal('rateLimitFingerprint') ?? generateFingerprint(exclude_ua: true);
$identity = $request->getGlobal('rateLimitIdentity') ?? $this->resolveIdentityFromJwt();
$this->limiter->recordIpFailure($fingerprint);

View File

@ -1069,7 +1069,7 @@ function getRealClientIP()
return $request->getIPAddress();
}
function generateFingerprint(): string
function generateFingerprint(bool $exclude_ua = false): string
{
$request = service('request');
@ -1097,6 +1097,9 @@ function generateFingerprint(): string
$ipGroup = 'unknown';
}
if($exclude_ua){
return hash('sha256', $ipGroup);
}
return hash('sha256', $ua . '|' . $ipGroup);
}
@ -1203,4 +1206,74 @@ if (!function_exists('map_relationship')) {
}
/**
* Extract identity from POST body or GET params.
* Looks for 'email' or 'mobile_number'.
*/
function resolveIdentity($request): ?string
{
// Try POST body first
$email = $request->getPost('email');
// print_r($email);die;
$mobile = $request->getPost('mobile_number');
// Fallback to GET params
if (! $email && ! $mobile) {
$email = $request->getGet('email');
$mobile = $request->getGet('mobile_number');
}
// Fallback to JSON params
if (! $email && ! $mobile) {
$req_data = $request->getJSON();
// print_r( $req_data);
$mobile = $req_data->mobile_number ?? null;
// return trim($mobile_number);
$email = $req_data->email ?? null;
if (!$email)
{
$email = $req_data->email_id ?? null;
}
// return trim($email);
}
if ($email) {
return strtolower(trim($email));
}
if ($mobile) {
return trim($mobile);
}
return null;
}
function recordRateLimitFailure(string $context = 'authApi'): void
{
/** @var IncomingRequest $request */
$request = \Config\Services::request();
$limiter = \Config\Services::limiter(); // or your custom limiter service
$fingerprint = $request->getVar('rateLimitFingerprint')
?? generateFingerprint(exclude_ua: true);
$identity = $request->getVar('rateLimitIdentity')
?? resolveIdentity($request);
// Record IP-level failure
$limiter->recordIpFailure($fingerprint);
// Record user-level failure
if (!empty($identity)) {
$limiter->recordUserFailure($identity, $context);
}
}

View File

@ -111,6 +111,7 @@ class RateLimiterService
'level' => $level,
'blocked_at' => time(),
'fingerprint'=> $fingerprint,
'ip' => getRealClientIP(),
];
// Duration 0 = store for 10 years (permanent until manual unblock)