Files
2026-09-16 23:20:08 +07:00

50 lines
1.6 KiB
PHP

<?php
namespace App\Middleware;
use App\Helpers\Response;
use App\Helpers\Security;
use App\Models\Model;
/**
* Class RateLimitMiddleware
* Enterprise API Rate Limiter & DDOS Mitigation Guard
*
* @package App\Middleware
*/
class RateLimitMiddleware
{
/**
* Handle rate limiting check (Max 60 requests per minute per IP)
*/
public static function handle(int $maxRequests = 60, int $windowSeconds = 60): void
{
$ip = Security::getClientIp();
$key = "rate_limit:ip:" . md5($ip);
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
// Use Session / APCu / Redis / File-based tracking for clean fallback without crashing if Redis is offline
$now = time();
$record = $_SESSION[$key] ?? ['count' => 0, 'start' => $now];
if (($now - $record['start']) >= $windowSeconds) {
$record = ['count' => 1, 'start' => $now];
} else {
$record['count']++;
}
$_SESSION[$key] = $record;
// Set Rate Limit Headers
header("X-RateLimit-Limit: {$maxRequests}");
header("X-RateLimit-Remaining: " . max(0, $maxRequests - $record['count']));
header("X-RateLimit-Reset: " . ($record['start'] + $windowSeconds));
if ($record['count'] > $maxRequests) {
Response::error("Too Many Requests: ท่านส่งคำขอเข้ามาถี่เกินไป กรุณารอ 1 นาทีก่อนลองใหม่อีกครั้ง (DDOS Protection)", 429);
}
}
}