Saltar al contenido

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

Nuestros programadores estrellas agotaron sus provisiones de café, por su búsqueda diariamente por la solución, hasta que Martín halló el resultado en GitLab por lo tanto ahora la compartimos aquí.

Solución:

Mirando la API de Laravel:

Request::ip();

Internamente, utiliza el getClientIps desde el 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+.)3d+):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);
 

Si está bajo un balanceador de carga, Laravel’s Request::ip()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 real del cliente:

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 
        
    
    return request()->ip(); // it will return server ip when no client ip found

Además de esto, te sugiero que tengas mucho cuidado con el uso de Laravel. acelerador middleware: Utiliza el de Laravel Request::ip() también, por lo que todos sus visitantes serán identificados como el mismo usuario y alcanzará el límite de aceleración muy rápidamente. Experimenté esto en vivo y esto causó grandes problemas.

Para arreglar esto:

IluminarHttpSolicitud.php

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

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

Usar request()->ip().

Por lo que entiendo, desde Laravel 5 se recomienda / es una buena práctica usar funciones globales como:

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

Y, en todo caso, al usar las funciones en lugar de las static notación mi IDE no se ilumina como un árbol de Navidad.

Te mostramos comentarios y valoraciones

Tienes la posibilidad dar difusión a esta crónica si te fue útil.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *