我們真的能通過請求來獲取使用者真實的ip地址嘛?
答案是不能,如果能,肯定是我學的不夠深入,歡迎交流指正。
那麼寫這篇文章的意義是什麼?我們接著往下看。
IP地址相當於電腦在網路上的身份證,但事實上IP地址卻沒有想象中那麼簡單,IP也分很多種,比如經常提到內網IP和外網IP。
外網ip和內網ip的區別是什麼?
我自己也對這個是比較模糊的,我就按照自己的理解大概解釋一遍。但是我講的不一定是對的。
我家裡的路由器是電信的,路由器上面連線一根電信的電話線,這跟電話線是要我家去電信繳費,才能上網。我家路由器能上網之後,就能開啟wifi,我的其他裝置就能通過wifi連線上這臺路由器。
上面介紹了個大概,接下來說說java端如何獲取訪問者 IP ?,先上程式碼
@Slf4j public class IpUtil { /** * 獲取使用者ip地址 * * @param request 請求 * @return ip地址 */ public static String getIpAddr(HttpServletRequest request) { String ipAddress = request.getHeader("X-Original-Forwarded-For"); log.info("X-Original-Forwarded-For:獲取的ipAddress{}",ipAddress); if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = request.getHeader("X-Forwarded-For"); log.info("X-Forwarded-For:獲取的ipAddress{}",ipAddress); } // 對於通過多個代理的情況,因為ip長度最大為15,如果超過了15就代表有1個以上的ip,這時我們就取第一個,多個IP按照','分割 if (ipAddress != null && ipAddress.length() > 15) { log.info("多個ip情況:獲取的ipAddress:{}",ipAddress); if (ipAddress.indexOf(",") > 0) { ipAddress = ipAddress.substring(0, ipAddress.indexOf(",")); } } if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { // apache http伺服器的請求 ipAddress = request.getHeader("Proxy-Client-IP"); log.info("Proxy-Client-IP:獲取的ipAddress{}",ipAddress); } if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { // apache http伺服器的請求,使用weblogic外掛加上的頭 ipAddress = request.getHeader("WL-Proxy-Client-IP"); log.info("WL-Proxy-Client-IP:獲取的ipAddress{}",ipAddress); } if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { // 有些代理伺服器會加上此請求頭 ipAddress = request.getHeader("HTTP_CLIENT_IP"); log.info("HTTP_CLIENT_IP:獲取的ipAddress{}",ipAddress); } if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = request.getHeader("HTTP_X_FORWARDED_FOR"); log.info("HTTP_X_FORWARDED_FOR:獲取的ipAddress{}",ipAddress); } if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { // nginx代理伺服器會加上此請求頭 ipAddress = request.getHeader("X-Real-IP"); log.info("X-Real-IP:獲取的ipAddress{}",ipAddress); } // 沒有使用代理的情況 if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = request.getRemoteAddr(); log.info("request.getRemoteAddr()------->{}",ipAddress); } // 如果用localhost來訪問會返回0:0:0:0:0:0:0:1,這裡我們將它轉換為127.0.0.1 return "0:0:0:0:0:0:0:1".equals(ipAddress)?"127.0.0.1":ipAddress; } }
這段程式碼看起來很長,其實有用的部分就是 request.getRemoteAddr();
X-Original-Forwarded-For
Proxy-Client-IP
HTTP_CLIENT_IP
HTTP_X_FORWARDED_FOR
這些都是一些常用的,因為這個請求頭型別是可以自定義的,所以我們根據請求頭型別獲取ip地址是不現實的。
但是為什麼程式碼裡面要寫呢?人情世故嘛,萬一公司是按程式碼行數算工資的呢。哈哈,開個玩笑,已知的代理請求頭,我們還是需要寫上去的。
不結合客戶使用場景的光討論技術都是耍流氓。下面我們重點說一下使用場景。
1、上面那段程式碼部署在外網環境,那麼獲取到的就是外網的ip,要是別人沒有經過偽裝,恭喜你,成功拿到他的ip。要是別人特意偽裝,你拿到這個ip或許是假的,沒有任何意義。
2、上面那段程式碼部署在內網環境,那麼獲取到的就是內網ip,這個內網ip,就能查出具體某臺電腦,也能在內網中遠端控制你的電腦。
上面兩個場景都是人畜無害。
一般是第二種情況使用的多。
比如你的公司有20層,公司所有員工都是用內網,你在20樓,你的同事在1樓,恰好你們公司沒有電梯,此時你想控制他的電腦,幫她處理一些事情,你就可以讓她直接訪問那段程式碼,獲取到她的ip地址。當然,程式碼肯定是封裝成一個介面,不然妹子怎麼訪問。
什麼?遠端不用向日葵?TV?QQ?
什麼?直接叫妹子從電腦檢視ip地址發給我?
哈哈,是我格局小了。我就怕妹子不會看啊。
難不成讓她自己百度怎麼檢視ip地址?老實說,有這種想法的是不是還單身?
好了,對於獲取ip地址,網上也是各種形形色色,但是要明確使用場景,如果你真的想通過一個ip地址去追尋到一個人或者一臺電腦,在公網環境下,有點不現實。但是在內網環境中,這個確實可行。