獲取客戶端使用者真實ip方法整理(jekyll遷移)
阿新 • • 發佈:2020-08-11
layout: post
title: 獲取客戶端使用者真實ip方法整理
date: 2019-08-22
author: xiepl1997
tags: springboot
由請求獲取客戶端ip地址的方法是request.getRemoteAddr(),在大部分的情況下該方法是有效的,但是在通過了apache、squid等反向代理軟體就不能獲取到客戶端的真實ip了。
經過代理後,由於在客戶端和服務之間增加了中間層,因此伺服器無法直接拿取到使用者的ip地址,伺服器端應用也無法直接通過轉發請求的地址返回給客戶端。但在轉發請求的HTTP頭資訊中,增加了X-FORWARDED-FOR資訊,用以跟蹤原有客戶端ip地址和原來客戶端的請求的伺服器地址。
獲取客戶端真實ip地址的方法如下
/** * @param request * @return 返回使用者的IP地址 */ public String getUserIp(HttpServletRequest request){ String ip = request.getHeader("X-Forwarded-For"); if(ip == null || ip.length() == 0 || "unknow".equalsIgnoreCase(ip)){ ip = request.getHeader("Proxy-Client-IP"); } if(ip == null || ip.length() == 0 || "unknow".equalsIgnoreCase(ip)){ ip = request.getHeader("WL-Proxy-Client-IP"); } if(ip == null || ip.length() == 0 || "unknow".equalsIgnoreCase(ip)){ ip = request.getHeader("HTTP_CLIENT_IP"); } if(ip == null || ip.length() == 0 || "unknow".equalsIgnoreCase(ip)){ ip = request.getHeader("HTTP_X_FORWARDED_FOR"); } if(ip == null || ip.length() == 0 || "unknow".equalsIgnoreCase(ip)){ ip = request.getRemoteAddr(); } return ip; }
這些請求頭的意思:
- X-Forwarded-For
這是一個 Squid 開發的欄位,只有在通過了HTTP代理或者負載均衡伺服器時才會新增該項。 - Proxy-Client-IP/WL- Proxy-Client-IP
這個一般是經過apache http伺服器的請求才會有,用apache http做代理時一般會加上Proxy-Client-IP請求頭,而WL-Proxy-Client-IP是他的weblogic外掛加上的頭。 - HTTP_CLIENT_IP
有些代理伺服器會加上此請求頭。
(2019-08-24 補)
測試的時候因為用到自己電腦測試,於是用上訴方法會得到127.0.0.1的本地環回地址,為了獲取到本機的ip地址,加上以下程式碼
if(ip.equals("127.0.0.1")){
//根據網絡卡獲取ip
InetAddress inet = null;
try {
inet = InetAddress.getLocalHost();
}catch (UnknownHostException e){
e.printStackTrace();
}
ip = inet.getHostAddress();
}