¿Cómo obtener la dirección IP del cliente en Laravel 5+?

Estoy tratando de obtener la dirección IP del cliente en Laravel. Como todos sabemos, es mucho más fácil obtener la IP de un cliente en PHP usando $_SERVER["REMOTE_ADDR"] .

Está funcionando bien en el núcleo de PHP, pero cuando uso la misma cosa en Laravel, entonces da el IP del servidor en lugar del IP del visitante.

Mirando la API de Laravel :

 Request::ip(); 

Internamente, usa el método getClientIps del Objeto de solicitud de Symfony :

 public function getClientIps() { $clientIps = array(); $ip = $this->server->get('REMOTE_ADDR'); if (!$this->isFromTrustedProxy()) { return array($ip); } if (self::$trustedHeaders[self::HEADER_FORWARDED] && $this->headers->has(self::$trustedHeaders[self::HEADER_FORWARDED])) { $forwardedHeader = $this->headers->get(self::$trustedHeaders[self::HEADER_FORWARDED]); preg_match_all('{(for)=("?\[?)([a-z0-9\.:_\-/]*)}', $forwardedHeader, $matches); $clientIps = $matches[3]; } elseif (self::$trustedHeaders[self::HEADER_CLIENT_IP] && $this->headers->has(self::$trustedHeaders[self::HEADER_CLIENT_IP])) { $clientIps = array_map('trim', explode(',', $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_IP]))); } $clientIps[] = $ip; // Complete the IP chain with the IP the request actually came from $ip = $clientIps[0]; // Fallback to this when the client IP falls into the range of trusted proxies foreach ($clientIps as $key => $clientIp) { // Remove port (unfortunately, it does happen) if (preg_match('{((?:\d+\.){3}\d+)\:\d+}', $clientIp, $match)) { $clientIps[$key] = $clientIp = $match[1]; } if (IpUtils::checkIp($clientIp, self::$trustedProxies)) { unset($clientIps[$key]); } } // Now the IP chain contains only untrusted proxies and the client IP return $clientIps ? array_reverse($clientIps) : array($ip); } 

Utilizar request()->ip()

Desde Laravel 5 (por lo que entiendo) se aconseja / buena práctica usar las funciones globales como:

 response()->json($v); view('path.to.blade'); redirect(); route(); cookie(); 

Obtiene el punto 🙂 Y, en todo caso, al usar las funciones (en lugar de la notarización estática) mi IDE no se enciende como un árbol de Navidad 😉

Si estás bajo un equilibrador de carga

\Request::ip() Laravel siempre devuelve la IP del balanceador

  echo $request->ip(); // server ip echo \Request::ip(); // server ip echo \request()->ip(); // server ip echo $this->getIp(); //see the method below // clent ip 

Este método personalizado devuelve la ip del cliente real:

 public function getIp(){ foreach (array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR') as $key){ if (array_key_exists($key, $_SERVER) === true){ foreach (explode(',', $_SERVER[$key]) as $ip){ $ip = trim($ip); // just to be safe if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false){ return $ip; } } } } } 

Más: si utiliza el middleware del acelerador de Laravel

Además, le sugiero que tenga mucho cuidado al usar el middleware del acelerador de Laravel: también utiliza la Request::ip() de Laravel Request::ip() , por lo que todos sus visitantes serán identificados como el mismo usuario y usted alcanzará el límite del acelerador muy rápidamente. . Experimentado en vivo … esto me llevó a grandes problemas …

Para arreglar esto:

Illuminate \ Http \ Request.php

  public function ip() { //return $this->getClientIp(); //original method return $this->getIp(); // the above method } 

Ahora también puede usar Request::ip() , que debería devolver la IP real en producción

Añadir espacio de nombres

 use Request; 

Entonces llama a la función

 Request::ip(); 

Para Laravel 5 puedes usar el objeto Request. Simplemente llama a su método ip (). Algo como:

$request->ip();

En Laravel 5

 public function index(Request $request) { $request->ip(); } 

En la versión 5.4 de laravel, no podemos llamar a ip static, esta es una forma correcta de obtener un usuario ip

  use Illuminate\Http\Request; public function contactUS(Request $request) { echo $request->ip(); return view('page.contactUS'); } 

Si desea la IP del cliente y su servidor está detrás de aws elb, entonces utilice el siguiente código. Probado para laravel 5.3

 $elbSubnet = '172.31.0.0/16'; Request::setTrustedProxies([$elbSubnet]); $clientIp = $request->ip(); 

Si llama a esta función, obtendrá fácilmente la dirección IP del cliente. Ya he usado este código útil en mi proyecto existente.

 public function getUserIpAddr(){ $ipaddress = ''; if (isset($_SERVER['HTTP_CLIENT_IP'])) $ipaddress = $_SERVER['HTTP_CLIENT_IP']; else if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR']; else if(isset($_SERVER['HTTP_X_FORWARDED'])) $ipaddress = $_SERVER['HTTP_X_FORWARDED']; else if(isset($_SERVER['HTTP_FORWARDED_FOR'])) $ipaddress = $_SERVER['HTTP_FORWARDED_FOR']; else if(isset($_SERVER['HTTP_FORWARDED'])) $ipaddress = $_SERVER['HTTP_FORWARDED']; else if(isset($_SERVER['REMOTE_ADDR'])) $ipaddress = $_SERVER['REMOTE_ADDR']; else $ipaddress = 'UNKNOWN'; return $ipaddress; } 

Si aún obtiene 127.0.0.1 como IP, debe agregar su “proxy”.

¡Pero ten en cuenta que tienes que cambiarlo antes de ir a la producción!

Lea esta parte: https://laravel.com/docs/5.7/requests#configuring-trusted-proxies

Y ahora solo agrega esto:

 class TrustProxies extends Middleware { /** * The trusted proxies for this application. * * @var array */ protected $proxies = '*'; 

Ahora request () -> ip () te da la ip correcta

Hay 2 cosas que cuidar

1) obtener la función de ayuda que devuelve un método Illuminate\Http\Request and call ->ip() .

 request()->ip(); 

2) Piense en la configuración de su servidor, puede usar proxy o load balancer (especialmente en la configuración de AWS ELB )

Si este es su caso, necesita configurar Proxies de confianza o tal vez incluso configurar una opción Trusting All Proxies .

¿Por qué?

Porque al ser su servidor, obtendremos su IP de proxy / balance-loader en su lugar.

¿Cómo?

Si usted no es un AWS balance-loader

Vaya a App\Http\Middleware\TrustProxies

y hacer que la statement de $proxies vea así:

 protected $proxies = '*'; 

Ahora pruébelo y sea bueno, porque se salvó de tener problemas con throttle middleware . También se basa en request()->ip() y, sin configurar TrustProxies , puede bloquear a todos los usuarios para que no inicien sesión en lugar de bloquear solo la IP del responsable.

Y como throttle middleware no se explica correctamente en la documentación, recomiendo ver este video

Probado en Laravel 5.7

Cuando queramos la ip_address del usuario:

 $_SERVER['REMOTE_ADDR'] 

y desea la dirección del servidor:

 $_SERVER['SERVER_ADDR']