1、不适用负载代理
在JavaWeb中获取客户端IP地址只需要使用request.getRemoteAddr();
String userIP = request.getRemoteAddr();
2、使用Nginx等反向代理
2.1、Ngin配置
server {
listen 80;
server_name xxx.xxxx.com;
location / {
#保留代理之前的host 包含客户端真实的域名和端口号
proxy_set_header Host $host;
#保留代理之前的真实客户端ip
proxy_set_header X-Real-IP $remote_addr;
#这个Header和X-Real-IP类似,但它在多级代理时会包含真实客户端及中间每个代理服务器的IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#表示客户端真实的协议(http还是https)
proxy_set_header X-Forwarded-Proto $scheme;
#指定修改被代理服务器返回的响应头中的location头域跟refresh头域数值
#如果使用"default"参数,将根据location和proxy_pass参数的设置来决定。
#proxy_redirect [ default|off|redirect replacement ];
proxy_redirect off;
proxy_pass http://IP:PORT;
}
}
如果使用了Nginx等反向代理的话,使用request.getRemoteAddr();方法获取到的IP地址就是127.0.0.1,因为经过代理以后,在客户端和服务器之间增加了中间层,因此服务器无法直接拿到客户端的 IP,但是在转发请求的HTTP头信息中,增加了X-FORWARDED-FOR信息。用以跟踪原有的客户端IP地址和原来客户端请求的服务器地址所以我们可以通过
String userIP = request.getHeader("x-forwarded-for");
3、获取IP方法
public String getIpAddr(HttpServletRequest request) {
//获取请求头"x-forwarded-for"对应的value
String userIp = request.getHeader("x-forwarded-for");
//如果获取的ip值为空
if(userIp == null || userIp .length() == 0 || "unknown".equalsIgnoreCase(userIp )) {
//则获取请求头"Proxy-Client-IP"对应的value
userIp = request.getHeader("Proxy-Client-IP");
}
//如果获取的ip值仍为空
if(userIp == null || userIp .length() == 0 || "unknown".equalsIgnoreCase(userIp )) {
//则获取请求头"WL-Proxy-Client-IP"对应的value
userIp = request.getHeader("WL-Proxy-Client-IP");
}
//如果以上方式获取的ip值都为空
if(userIp == null || userIp .length() == 0 || "unknown".equalsIgnoreCase(userIp )) {
//则直接获取ip地址
userIp = request.getRemoteAddr();
}
//返回ip地址
return userIp;
}