代理http請求獲取客戶端IP
外界流傳的JAVA/PHP伺服器端獲取客戶端IP都是這麼取的: 虛擬碼: 1)ip = request.getHeader("X-FORWARDED-FOR ") 2)如果該值為空或陣列長度為0或等於"unknown",那麼: ip = request.getHeader("Proxy-Client-IP") 3)如果該值為空或陣列長度為0或等於"unknown",那麼: ip = request.getHeader("WL-Proxy-Client-IP") 4)如果該值為空或陣列長度為0或等於"unknown",那麼: ip = request.getHeader("HTTP_CLIENT_IP") 5)如果該值為空或陣列長度為0或等於"unknown",那麼:
ip = request.getHeader("X-Real-IP")
6)如果該值為空或陣列長度為0或等於"unknown",那麼:
ip = request.getRemoteAddr ()
先說說這些請求頭的意思
X-Forwarded-For
這是一個 Squid 開發的欄位,只有在通過了 HTTP 代理或者負載均衡伺服器時才會新增該項。格式為X-Forwarded-For: client1, proxy1, proxy2,一般情況下,第一個ip為客戶端真實ip,後面的為經過的代理伺服器ip。現在大部分的代理都會加上這個請求頭
Proxy-Client-IP/WL- Proxy-Client-IP
這個一般是經過apache http伺服器的請求才會有,用apache http做代理時一般會加上Proxy-Client-IP請求頭,而WL- Proxy-Client-IP是他的weblogic外掛加上的頭
HTTP_CLIENT_IP
有些代理伺服器會加上此請求頭
X-Real-IP
nginx代理一般會加上此請求頭。
有幾點要注意
1、這些請求頭都不是http協議裡的標準請求頭,也就是說這個是各個代理伺服器自己規定的表示客戶端地址的請求頭。如果哪天有一個代理伺服器軟體用oooo-client-ip這個請求頭代表客戶端請求,那上面的程式碼就不行了。
2、這些請求頭不是代理伺服器一定會帶上的,網路上的很多匿名代理就沒有這些請求頭,所以獲取到的客戶端ip不一定是真實的客戶端ip。代理伺服器一般都可以自定義請求頭設定。
3、即使請求經過的代理都會按自己的規範附上代理請求頭,上面的程式碼也不能確保獲得的一定是客戶端ip。不同的網路架構,判斷請求頭的順序是不一樣的。
4、最重要的一點,請求頭都是可以偽造的。如果一些對客戶端校驗較嚴格的應用(比如投票)要獲取客戶端ip,應該直接使用ip = request.getRemoteAddr (),雖然獲取到的可能是代理的ip而不是客戶端的ip,但這個獲取到的ip基本上是不可能偽造的,也就杜絕了刷票的可能。(有分析說arp欺騙+syn有可能偽造此ip,如果真的可以,這是所有基於TCP協議都存在的漏洞),這個ip是tcp連線裡的ip。 --------------------- 作者:fengwind1 來源:CSDN 原文:https://blog.csdn.net/fengwind1/article/details/51992528 版權宣告:本文為博主原創文章,轉載請附上博文連結!