Pregunta ¿Cómo obtener la dirección IP del cliente en PHP?


¿Cómo puedo obtener la dirección IP del cliente usando PHP?

Quiero mantener un registro del usuario que inició sesión en mi sitio web a través de su dirección IP.


977
2018-06-09 04:50


origen


Respuestas:


Hagas lo que hagas, asegúrate de no confiar en los datos enviados por el cliente. $_SERVER['REMOTE_ADDR'] contiene la dirección IP real de la parte que se conecta. Ese es el valor más confiable que puede encontrar.

Sin embargo, pueden estar detrás de un servidor proxy en cuyo caso el proxy puede haber configurado el $_SERVER['HTTP_X_FORWARDED_FOR'], pero este valor es fácilmente falsificado. Por ejemplo, puede ser configurado por alguien sin un proxy, o la IP puede ser una IP interna de la LAN detrás del proxy.

Esto significa que si vas a guardar el $_SERVER['HTTP_X_FORWARDED_FOR'], Asegúrese además salva el $_SERVER['REMOTE_ADDR'] valor. P.ej. guardando ambos valores en diferentes campos en su base de datos.

Si va a guardar la IP en una base de datos como una cadena, asegúrese de tener espacio para al menos 45 caracteres. IPv6 llegó para quedarse y esas direcciones son más grandes que las direcciones IPv4 antiguas.

(Tenga en cuenta que IPv6 generalmente usa 39 caracteres como máximo, pero también hay un especial Notación de IPv6 para direcciones IPv4 que en su forma completa puede tener hasta 45 caracteres. Entonces, si sabes lo que estás haciendo, puedes usar 39 caracteres, pero si solo quieres establecerlo y olvidarlo, usa 45).


1163
2018-06-09 05:15



$_SERVER['REMOTE_ADDR'] puede que no contenga direcciones IP reales del cliente, ya que le dará una dirección proxy para clientes conectados a través de un proxy, por ejemplo. Que puede bueno, sé lo que realmente quieres, dependiendo de lo que hagas con los IP. La dirección RFC1918 privada de alguien puede no servirle de nada, por ejemplo, tratando de ver de dónde se origina el tráfico, o recordando de qué IP se conectó el usuario por última vez, donde la IP pública del proxy o la puerta de enlace NAT podría ser más apropiado para almacenar

Hay varios encabezados HTTP como X-Forwarded-For que puede o no ser establecido por varios proxies. El problema es que esos son simplemente encabezados HTTP que cualquier persona puede configurar. No hay garantía sobre su contenido. $_SERVER['REMOTE_ADDR'] es la dirección IP física real de la que el servidor web recibió la conexión y a la que se enviará la respuesta. Cualquier otra cosa es solo información arbitraria y voluntaria. Solo hay un escenario en el que puede confiar en esta información: está controlando el proxy que establece este encabezado. Es decir, solo si sabes al 100% dónde y cómo se configuró el encabezado, si lo haces por algo importante.

Habiendo dicho eso, aquí hay un código de muestra:

if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
    $ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
    $ip = $_SERVER['REMOTE_ADDR'];
}

Nota del editor: Usando el código anterior tiene implicaciones de seguridad. El cliente puede establecer toda la información del encabezado HTTP (es decir. $_SERVER['HTTP_...) a cualquier valor arbitrario que quiera. Como tal, es mucho más confiable de usar $_SERVER['REMOTE_ADDR'], ya que esto no puede ser establecido por el usuario.

De: http://roshanbh.com.np/2007/12/getting-real-ip-address-in-php.html


376
2017-09-11 04:01



echo $_SERVER['REMOTE_ADDR'];

http://php.net/manual/en/reserved.variables.server.php


185
2018-06-09 04:51



Debería estar contenido en $_SERVER['REMOTE_ADDR'] variable.


79
2017-09-11 03:38



Aquí hay una muestra del código más limpio de una buena forma de obtener la ip del usuario.

$ip = $_SERVER['HTTP_CLIENT_IP']?$_SERVER['HTTP_CLIENT_IP']:($_SERVER['HTTP_X_FORWARDE‌​D_FOR']?$_SERVER['HTTP_X_FORWARDED_FOR']:$_SERVER['REMOTE_ADDR']);

Aquí hay una versión más corta que usa el operador elvis

$_SERVER['HTTP_CLIENT_IP']?:($_SERVER['HTTP_X_FORWARDE‌​D_FOR']?:$_SERVER['REMOTE_ADDR']);

Aquí hay una versión que usa isset para eliminar avisos (gracias, @shasi kanth)

$ip = isset($_SERVER['HTTP_CLIENT_IP'])?$_SERVER['HTTP_CLIENT_IP']:isset($_SERVER['HTTP_X_FORWARDED_FOR'])?$_SERVER['HTTP_X_FORWARDED_FOR']:$_SERVER['REMOTE_ADDR'];

79
2017-10-08 16:20



Mi solución favorita es la forma en que Zend Framework 2 usa. También considera el $_SERVER propiedades HTTP_X_FORWARDED_FOR, HTTP_CLIENT_IP, REMOTE_ADDR pero declara una clase para que establezca algunos proxies de confianza y devuelve una dirección IP, no una matriz. Creo que esta es la solución que más se acerca:

class RemoteAddress
{
    /**
     * Whether to use proxy addresses or not.
     *
     * As default this setting is disabled - IP address is mostly needed to increase
     * security. HTTP_* are not reliable since can easily be spoofed. It can be enabled
     * just for more flexibility, but if user uses proxy to connect to trusted services
     * it's his/her own risk, only reliable field for IP address is $_SERVER['REMOTE_ADDR'].
     *
     * @var bool
     */
    protected $useProxy = false;

    /**
     * List of trusted proxy IP addresses
     *
     * @var array
     */
    protected $trustedProxies = array();

    /**
     * HTTP header to introspect for proxies
     *
     * @var string
     */
    protected $proxyHeader = 'HTTP_X_FORWARDED_FOR';

    // [...]

    /**
     * Returns client IP address.
     *
     * @return string IP address.
     */
    public function getIpAddress()
    {
        $ip = $this->getIpAddressFromProxy();
        if ($ip) {
            return $ip;
        }

        // direct IP address
        if (isset($_SERVER['REMOTE_ADDR'])) {
            return $_SERVER['REMOTE_ADDR'];
        }

        return '';
    }

    /**
     * Attempt to get the IP address for a proxied client
     *
     * @see http://tools.ietf.org/html/draft-ietf-appsawg-http-forwarded-10#section-5.2
     * @return false|string
     */
    protected function getIpAddressFromProxy()
    {
        if (!$this->useProxy
            || (isset($_SERVER['REMOTE_ADDR']) && !in_array($_SERVER['REMOTE_ADDR'], $this->trustedProxies))
        ) {
            return false;
        }

        $header = $this->proxyHeader;
        if (!isset($_SERVER[$header]) || empty($_SERVER[$header])) {
            return false;
        }

        // Extract IPs
        $ips = explode(',', $_SERVER[$header]);
        // trim, so we can compare against trusted proxies properly
        $ips = array_map('trim', $ips);
        // remove trusted proxy IPs
        $ips = array_diff($ips, $this->trustedProxies);

        // Any left?
        if (empty($ips)) {
            return false;
        }

        // Since we've removed any known, trusted proxy servers, the right-most
        // address represents the first IP we do not know about -- i.e., we do
        // not know if it is a proxy server, or a client. As such, we treat it
        // as the originating IP.
        // @see http://en.wikipedia.org/wiki/X-Forwarded-For
        $ip = array_pop($ips);
        return $ip;
    }

    // [...]
}

Vea el código completo aquí: https://raw.githubusercontent.com/zendframework/zend-http/master/src/PhpEnvironment/RemoteAddress.php


47
2017-07-07 09:02



Hay diferentes tipos de usuarios detrás de Internet, por lo que queremos captar la dirección IP de diferentes pociones. Que son,

1. $_SERVER['REMOTE_ADDR'] - Esto contiene la dirección IP real del cliente. Ese es el valor más confiable que puede encontrar del usuario.

2. $_SERVER['REMOTE_HOST'] - Esto obtendrá el nombre de Host desde el cual el usuario está viendo la página actual. Pero para que este script funcione, las búsquedas de nombres de host en el interior de httpd.conf deben configurarse.

3. $_SERVER['HTTP_CLIENT_IP'] - Esto obtendrá la dirección IP cuando el usuario proviene de servicios de Internet compartidos.

4. $_SERVER['HTTP_X_FORWARDED_FOR'] - Esto obtendrá la dirección IP del usuario cuando esté detrás del proxy

Entonces podemos usar esta siguiente función combinada para obtener la dirección IP real de los usuarios que están viendo en diferentes posiciones,

// Function to get the user IP address
function getUserIP() {
    $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_X_CLUSTER_CLIENT_IP']))
        $ipaddress = $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
    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;
}

34
2017-12-29 15:18