En doğru yol almak bir kullanıcı'PHP nin doğru IP adresi nedir? | Netgez.com
SORU
28 EKİM 2009, ÇARŞAMBA


En doğru yol almak bir kullanıcı'PHP nin doğru IP adresi nedir?

Bir bolluk var$_SERVERdeğişkenler başlıkları için kullanılabilir alımı IP adresi. Eğer en doğru şekilde, bir kullanıcının gerçek IP adresini (iyi yöntem bilmek mükemmel) dedi değişkenleri kullanarak almak için nasıl genel bir fikir birliği varsa hiç merak ettim?

Biraz zaman derinliği içinde bir çözüm bulmak için uğraştım ve aşağıdaki kodu kaynaklardan bir dizi temel ile geldi. Eğer biri cevap ambalajda delik lütfen falan belki daha doğru biraz ışık tutabilir eğer çok sevinirim.

edit @Alix gelen iyileştirmeleri içerir

 /**
  * Retrieves the best guess of the client's actual IP address.
  * Takes into account numerous HTTP proxy headers due to variations
  * in how different ISPs handle IP addresses in headers between hops.
  */
 public function get_ip_address() {
  // Check for shared internet/ISP IP
  if (!empty($_SERVER['HTTP_CLIENT_IP']) && $this->validate_ip($_SERVER['HTTP_CLIENT_IP']))
   return $_SERVER['HTTP_CLIENT_IP'];

  // Check for IPs passing through proxies
  if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
   // Check if multiple IP addresses exist in var
    $iplist = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
    foreach ($iplist as $ip) {
     if ($this->validate_ip($ip))
      return $ip;
    }
   }
  }
  if (!empty($_SERVER['HTTP_X_FORWARDED']) && $this->validate_ip($_SERVER['HTTP_X_FORWARDED']))
   return $_SERVER['HTTP_X_FORWARDED'];
  if (!empty($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']) && $this->validate_ip($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']))
   return $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
  if (!empty($_SERVER['HTTP_FORWARDED_FOR']) && $this->validate_ip($_SERVER['HTTP_FORWARDED_FOR']))
   return $_SERVER['HTTP_FORWARDED_FOR'];
  if (!empty($_SERVER['HTTP_FORWARDED']) && $this->validate_ip($_SERVER['HTTP_FORWARDED']))
   return $_SERVER['HTTP_FORWARDED'];

  // Return unreliable IP address since all else failed
  return $_SERVER['REMOTE_ADDR'];
 }

 /**
  * Ensures an IP address is both a valid IP address and does not fall within
  * a private network range.
  *
  * @access public
  * @param string $ip
  */
 public function validate_ip($ip) {
     if (filter_var($ip, FILTER_VALIDATE_IP, 
                         FILTER_FLAG_IPV4 | 
                         FILTER_FLAG_IPV6 |
                         FILTER_FLAG_NO_PRIV_RANGE | 
                         FILTER_FLAG_NO_RES_RANGE) === false)
         return false;
     self::$ip = $ip;
     return true;
 }

Uyarı sözcükleri (update)

REMOTE_ADDR hala temsil ediyoren güvenilirbir IP adresi kaynağı. $_SERVER Diğer değişkenleri burada bahsedilen uzak bir istemci tarafından kolayca taklit edilebilir. Bu çözümün amacı, bir istemci bir proxy arkasında oturan IP adresini belirlemek için çalışmaktır. Genel amaçlı, IP adresini doğrudan $_SERVER['REMOTE_ADDR'] döndü ve iki depolama ile birlikte bu kullanarak düşünebilirsiniz.

Kullanıcıların ™.9 için bu çözüm mükemmel ihtiyaçlarınıza uygun olacaktır.Kötü niyetli kullanıcıların kendi istek baÅŸlıklarını enjekte ederek sisteminizi istismar etmek isteyen 0.1% sizi koruyacaktır. Bir ÅŸey için eÄŸer IP adresleri güvenmek durumunda kritik REMOTE_ADDR çare ve bir proxy arkasında olanlar ikram zahmet etmeyin.

CEVAP
9 Ocak 2010, CUMARTESÄ°


Burada daha kısa, daha temiz IP adresini almak için bir yol

function get_ip_address(){
    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;
                }
            }
        }
    }
}

Yardımcı olur umarım!


Kodunuz gibi görünüyor hoş tam zaten, göremiyorum herhangi bir olası hatalar (yana her zamanki IP uyarılar), I would change validate_ip() fonksiyon için itimat filtre uzatma ama

public function validate_ip($ip)
{
    if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) === false)
    {
        return false;
    }

    self::$ip = sprintf('%u', ip2long($ip)); // you seem to want this

    return true;
}

Ayrıca HTTP_X_FORWARDED_FOR parçacığını bu basitleştirilmiş olabilir:

// check for IPs passing through proxies
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
{
    // check if multiple ips exist in var
    if (strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ',') !== false)
    {
        $iplist = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);

        foreach ($iplist as $ip)
        {
            if ($this->validate_ip($ip))
                return $ip;
        }
    }

    else
    {
        if ($this->validate_ip($_SERVER['HTTP_X_FORWARDED_FOR']))
            return $_SERVER['HTTP_X_FORWARDED_FOR'];
    }
}

Bunun için:

// check for IPs passing through proxies
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
{
    $iplist = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);

    foreach ($iplist as $ip)
    {
        if ($this->validate_ip($ip))
            return $ip;
    }
}

Aynı zamanda IPv6 adreslerini doğrulamak isteyebilirsiniz.

Bunu PaylaÅŸ:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VÄ°DEO

Rastgele Yazarlar

  • Anthony Cumia

    Anthony Cumi

    5 EYLÃœL 2006
  • merumputdotcom

    merumputdotc

    24 ÅžUBAT 2012
  • sinumatic

    sinumatic

    19 Aralık 2006