老大說,網上這種獲取真實IP位址的方法不對,我不信

2019-10-30     程式設計師聖經
作者:蔡永吉
來源:https://blog.csdn.net/takeurhand/article/details/52512200

想必大家對這段代碼並不陌生:

是的,你搜索到的「java獲取真實IP位址」大多都是如此。但是,以上代碼真
的對嗎?

那麼我們看一下具體的代碼。如上,判斷ip地址的優先級是

"x-forwarded-for">
"Proxy-Client-IP">
"WL-Proxy-Client-IP">
request.getRemoteAddr()

其中帶引號的都是從header中獲取的。

等等!我們都知道header中的值是可以更改的。比如:

代碼出自:https://github.com/caiyongji/vote-2.0/blob/master/Vote-2.0.js

其中headers屬性X-Forwarded-For,WL-Proxy-Client-IP不就是被更改了嗎?

那麼,為什麼會有這個版本的「java獲取真實IP位址」的方法呢?並且搜尋引擎所能檢索到的結果大多都是這一個?

打個比方說,如果這個解決辦法是一本秘籍的話,那麼,我們找到的只是「java獲取真實IP位址」殘卷。

而剩下的部分在這裡:

#Nginx 設置
location ~ ^/static {
proxy_pass ....;
proxy_set_header X-Forward-For $remote_addr ;
}

這段配置是在前端Nginx反向代理上的(其他反向代理請自行搜索),這段配置

作的事情是將X-Forward-For替換為remote_addr,再將X-Forward-For在內網

各伺服器間安全傳輸。

這裡我再針對TCP/IP多做一些解釋,眾所周知TCP/IP建立連接時需要三次握手的,並且,只有知道了client端請求的IP位址,server端的數據才能返回給client,所以client想要獲取到數據就必須提供真實的IP(DDOS攻擊除外),而request.getRemoteAddr()獲取的就是用戶最真實的IP。

那麼為什麼不直接使用使用request.getRemoteAddr()這個方法呢?

如果沒有反向代理的話當然可行。但是出於安全原因,現在大多數的服務都使用代理伺服器(如Nginx,代理伺服器可以理解為用戶和伺服器之間的中介,雙方都可信任。),而用戶對代理伺服器發起的HTTP請求,代理伺服器對服務集群中的真實部署的對應服務進行「二次請求」,所以最終獲取的IP是代理伺服器在內網中的ip地址,如192.168.xx.xx/10.xx.xx.xx等等。

所以在使用了反向代理的情況下,request.getRemoteAddr()獲取的是反響代理在內網中的ip地址。所以在反向代理中將X-Forward-For替換為remote_addr,即,真實的IP位址。之後在內網中獲取的x-forwarded-for便是真實的ip地址了。

最後給出完整解決方案(Nginx為例):

JAVA部分:

Nginx部分:

location ~ ^/static {
proxy_pass ....;
proxy_set_header X-Forward-For $remote_addr ;
}
這就是差距啊~~~
文章來源: https://twgreatdaily.com/jXzyUW4BMH2_cNUgFlTw.html