Skip to content

Instantly share code, notes, and snippets.

@MikeCraig418
Created October 7, 2024 16:16
Show Gist options
  • Select an option

  • Save MikeCraig418/573d92ed7cc8d793cfc125d3eacfa09f to your computer and use it in GitHub Desktop.

Select an option

Save MikeCraig418/573d92ed7cc8d793cfc125d3eacfa09f to your computer and use it in GitHub Desktop.
<?php
namespace App\Http\Middleware\Concerns;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
abstract class AbstractBanManagement
{
protected const DEFAULT_BAN_DURATION = 86400; // 24 hours in seconds
abstract protected function shouldBan(Request $request): bool;
public function handle(Request $request, Closure $next)
{
$ip = $request->ip();
// Check if the IP is banned
if ($this->isIpBanned($ip)) {
return $this->banResponse();
}
// Check if the request should result in a ban
if ($this->shouldBan($request)) {
$this->banIp($ip);
return $this->banResponse();
}
return $next($request);
}
protected function isIpBanned(string $ip): bool
{
return Cache::has("banned_ip:{$ip}");
}
protected function banIp(string $ip, BanDuration|int $duration = self::DEFAULT_BAN_DURATION): void
{
$seconds = $duration instanceof BanDuration ? $duration->value : $duration;
Cache::put("banned_ip:{$ip}", true, now()->addSeconds($seconds));
}
protected function clearBan(string $ip): void
{
Cache::forget("banned_ip:{$ip}");
Cache::forget("offense_count:{$ip}");
Cache::forget("probe_attempts:{$ip}");
Cache::forget("404_count:{$ip}");
// Add any other counters or ban-related cache keys here
}
protected function banResponse()
{
return response()->json([
'error' => 'Too many requests',
'rate_limit' => [
'limit' => 100,
'remaining' => 0,
'reset' => time() + 3600,
],
], 429);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment