首頁  >  文章  >  後端開發  >  了解php獲取客戶端ip的方法

了解php獲取客戶端ip的方法

jacklove
jacklove原創
2018-05-22 11:38:422217瀏覽

本文說明如何透過php取得客戶端ip的方法

取得ip函數如下:

function getIP() {
    $realip = ''; //设置默认值
    if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $realip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
        $realip = $_SERVER['HTTP_CLIENT_IP'];
    } else {
        $realip = $_SERVER['REMOTE_ADDR'];
    }
    preg_match('/^((?:\d{1,3}\.){3}\d{1,3})/',$realip,$match);
        if($match && ipType($match[0]) == 'InterNet网地址'){
                return  $match[0];
        }else{
                return  false;
        }
}

//網路允許使用IP位址

function ipType($ip) {
    $iplist = explode(".", $ip);
    if ($iplist[0] >= 224 && $iplist[0] <= 239)
                return &#39;多播&#39;;
        if ($iplist[0] >= 240 && $iplist[0] <= 255)
        return &#39;保留&#39;;
    if (preg_match(&#39;/^198\.51\.100/&#39;, $ip))
        return &#39;TEST-NET-2,文档和示例&#39;;
    if (preg_match(&#39;/^203\.0\.113/&#39;, $ip))
        return &#39;TEST-NET-3,文档和示例&#39;;
    if (preg_match(&#39;/^192\.(18|19)\./&#39;, $ip))
        return &#39;网络基准测试&#39;;
    if (preg_match(&#39;/^192\.168/&#39;, $ip))
        return &#39;专用网络[内部网]&#39;;
    if (preg_match(&#39;/^192\.88\.99/&#39;, $ip))
        return &#39;ipv6to4中继&#39;;
    if (preg_match(&#39;/^192\.0\.2\./&#39;, $ip))
        return &#39;TEST-NET-1,文档和示例&#39;;
    if (preg_match(&#39;/^192\.0\.0\./&#39;, $ip))
        return &#39;保留(IANA)&#39;;
    if (preg_match(&#39;/^192\.0\.0\./&#39;, $ip))
        return &#39;保留(IANA)&#39;;
    if ($iplist[0] == 172 && $iplist[1] <= 31 && $iplist[1] >= 16)
        return &#39;专用网络[内部网]&#39;;
    if ($iplist[0] == 169 && $iplist[1] == 254)
        return &#39;链路本地&#39;;
    if ($iplist[0] == 127)
        return &#39;环回地址&#39;;
    if ($iplist[0] == 10)
        return &#39;专用网络[内部网]&#39;;
    if ($iplist[0] == 0)
        return &#39;本网络(仅作为源地址时合法)&#39;;
    return &#39;InterNet网地址&#39;;
}

   

#網路上常見取得ip函數如下:

public function get_real_ip() {
    static $realip;
    if (isset($_SERVER)) {
        if (isset($_SERVER[&#39;HTTP_X_FORWARDED_FOR&#39;])) {
            $realip = $_SERVER[&#39;HTTP_X_FORWARDED_FOR&#39;];
        } else if (isset($_SERVER[&#39;HTTP_CLIENT_IP&#39;])) {
            $realip = $_SERVER[&#39;HTTP_CLIENT_IP&#39;];
        } else {
            $realip = $_SERVER[&#39;REMOTE_ADDR&#39;];
        }
    } else {
        if (getenv(&#39;HTTP_X_FORWARDED_FOR&#39;)) {
            $realip = getenv(&#39;HTTP_X_FORWARDED_FOR&#39;);
        } else if (getenv(&#39;HTTP_CLIENT_IP&#39;)) {
            $realip = getenv(&#39;HTTP_CLIENT_IP&#39;);
        } else {
            $realip = getenv(&#39;REMOTE_ADDR&#39;);
        }
    }
    return $realip;
}

   

## 'REMOTE_ADDR' ,'HTTP_X_FORWARDED_FOR','HTTP_CLIENT_IP'之間的差異?

1.’REMOTE_ADDR’ 是遠端IP,預設來自tcp 連線是,客戶端的Ip。可以說,它最準確,確定是,只會得到直接連伺服器客戶端IP。如果對方透過代理伺服器上網,就發現。取得到的是代理伺服器IP了。

如:a->b(proxy)->c ,如果c 通過’REMOTE_ADDR’ ,只能取得到b的IP,取得不到a的IP了。

2.’HTTP_X_FORWARDED_FOR’,’HTTP_CLIENT_IP’ 為了能在大型網路中,取得到最原始用戶IP,或代理IP位址。對HTTp協定進行擴充。定義了實體頭。

HTTP_X_FORWARDED_FOR = clientip,proxy1,proxy2 所有IP用」,」分割。 HTTP_CLIENT_IP 在進階匿名代理中,這個代表了代理伺服器IP。既然是http協定擴充一個實體頭,而這個值對於傳入端是信任的,信任傳入者依照規則格式輸入的。以下以x_forword_for範例加以說明,正常情況下,這個值變化過程。

風險點所在:

這些變量,來自http請求的:x-forword-for字段,以及client-ip字段。正常代理伺服器,當然會依照rfc規範來傳入這些值。但是,當一個用戶直接建構該x-f​​orword-for值,傳送給用戶,這樣就好比就直接有一個可以寫入任意值的欄位。且伺服器直接讀取,或寫入資料庫,或做顯示。它將帶來危險性,跟一般對入輸入沒有做任何過濾檢測,之間操作資料來源結果一樣。

對於上面getip函數:

除了客戶端可以任意偽造IP,並且可以傳入任意格式IP。這樣結果會帶來2大問題,其一,如果你設定某個頁面,做IP限制。對方可以輕鬆修改IP不斷請求該頁面。其二,這類資料你如果直接使用,將帶來SQL註冊,跨站攻擊等漏洞。至於其一,可以在業務上面做限制,最好不要採用IP限制。對於其二,這類可以帶來巨大網路風險。我們必須加以糾正。

本文說明如何透過php取得客戶端ip的方法,更多相關內容請關注php中文網。

相關推薦:

php中關於Session的使用詳解

#php中die(),exit(),return的差異介紹

SQL 中on 條件與where 條件的差異

以上是了解php獲取客戶端ip的方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn