giftcon_dev/app/Http/Middleware/AdminIpAllowlist.php
2026-03-03 15:13:16 +09:00

53 lines
1.3 KiB
PHP

<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
final class AdminIpAllowlist
{
public function handle(Request $request, Closure $next): Response
{
$allowed = config('admin.allowed_ips', []);
// 개발(local/testing)에서는 allowlist 비어있으면 전체 허용
if (!$allowed && !app()->environment('production')) {
return $next($request);
}
if (!$allowed) {
abort(403, 'admin ip not allowed');
}
$ip = $request->ip();
foreach ($allowed as $rule) {
if ($this->matchIp($ip, $rule)) {
return $next($request);
}
}
abort(403, 'admin ip not allowed');
}
private function matchIp(string $ip, string $rule): bool
{
if (strpos($rule, '/') === false) {
return $ip === $rule;
}
[$subnet, $mask] = explode('/', $rule, 2);
$mask = (int) $mask;
$ipLong = ip2long($ip);
$subLong = ip2long($subnet);
if ($ipLong === false || $subLong === false || $mask < 0 || $mask > 32) return false;
$maskLong = -1 << (32 - $mask);
return (($ipLong & $maskLong) === ($subLong & $maskLong));
}
}