首先,先來看這道題的源碼:php
<?php function GetIP(){ if(!empty($_SERVER["HTTP_CLIENT_IP"])) $cip = $_SERVER["HTTP_CLIENT_IP"]; else if(!empty($_SERVER["HTTP_X_FORWARDED_FOR"])) $cip = $_SERVER["HTTP_X_FORWARDED_FOR"]; else if(!empty($_SERVER["REMOTE_ADDR"])) $cip = $_SERVER["REMOTE_ADDR"]; else $cip = "0.0.0.0"; return $cip; } $GetIPs = GetIP(); if ($GetIPs=="1.1.1.1"){ echo "Great! Key is *********"; } else{ echo "錯誤!你的IP不在訪問列表以內!"; } ?>
便是不懂PHP語言,也能看出來代碼的意思是若是IP是「1.1.1.1」,name就能獲取key值。因此,在咱們ip不是「1.1.1.1」的時候,怎麼作到這個呢?segmentfault
再根據上面的GetIP()代碼提示,判斷咱們IP會通過三步,首先檢測是HTTP_CLIENT_IP,它對應的是header中的client-ip,而後是HTTP_X_FORWARDED_FOR,它對應的header中的x-forwarded-for,服務器端HTTP_X_FORWARDED_FOR = clientip,proxy1,proxy2其中的值經過一個 逗號+空格 把多個IP地址區分開, 最左邊(client1)是最原始客戶端的IP地址, 代理服務器每成功收到一個請求,就把請求來源IP地址添加到右邊。服務器
最後檢測的是REMOTE_ADDR,這個參數不是客戶端可以操做的參數,它屬於TCP/IP的網絡層的東西,因此很難僞造(但不是不能夠呀,中轉器中好比路由器中是能夠實現的)。可是!!!前面都是客戶端提交http請求的頭部的內容啊,是能夠僞造的,因此此題就迎刃而解了。網絡
解法一:負載均衡
http頭部中添加:X-forwarded-for:1.1.1.1.net
解法二:代理
http頭部中添加:Client-IP:1.1.1.1code
兩種方法都可順利獲取key值。blog
深刻——怎麼防止IP僞造呢?ip
既然這麼輕鬆就能夠僞造IP地址了,服務器經過什麼方法獲取真實客戶端IP呢,REMOTE_ADDR雖然難以僞造,是服務器根據客戶端ip指定的,表明了真實的客戶端IP,可是通過代理服務器,或者負載均衡,CDN等設備以後,到達服務器,服務器會把REMOTE_ADDR值設爲這些中轉設備的ip,此時服務器就失去了真實的ip了。HTTP_CLIENT_IP 在通過代理後,也表明了代理服務器IP。
此時想到能夠在轉發時主動將X-forwarded-for配置爲正確的ip地址,將REMOTE_ADDR的值賦值給X-forwarded-for,這樣在離開了客戶端以後,便保存了真實的客戶端ip。
參考文獻:
一、https://blog.csdn.net/smilefyx/article/details/52120461
二、https://segmentfault.com/a/1190000007407810?utm_source=tag-newest