Files
slim-blog/src/Shared/Http/ClientIpResolver.php
2026-03-16 01:47:07 +01:00

59 lines
1.5 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Shared\Http;
use Psr\Http\Message\ServerRequestInterface;
/**
* Résout l'adresse IP cliente à partir de la requête HTTP.
*
* L'en-tête X-Forwarded-For n'est pris en compte que si REMOTE_ADDR
* correspond à un proxy explicitement approuvé. En l'absence d'IP
* exploitable, la valeur de repli '0.0.0.0' est renvoyée.
*/
final class ClientIpResolver
{
/**
* @param string[] $trustedProxies
*/
public function __construct(private readonly array $trustedProxies = [])
{
}
public function resolve(ServerRequestInterface $request): string
{
$serverParams = $request->getServerParams();
$remoteAddr = trim((string) ($serverParams['REMOTE_ADDR'] ?? ''));
if ($remoteAddr === '') {
return '0.0.0.0';
}
if (!$this->isTrustedProxy($remoteAddr)) {
return $remoteAddr;
}
$forwarded = trim((string) ($serverParams['HTTP_X_FORWARDED_FOR'] ?? ''));
if ($forwarded === '') {
return $remoteAddr;
}
$candidate = trim(explode(',', $forwarded)[0]);
return filter_var($candidate, FILTER_VALIDATE_IP) ? $candidate : $remoteAddr;
}
private function isTrustedProxy(string $remoteAddr): bool
{
foreach ($this->trustedProxies as $proxy) {
if ($proxy === '*' || $proxy === $remoteAddr) {
return true;
}
}
return false;
}
}