如何获取客户端真实IP

简介

  • 获取客户端的IP地址常用的方法是:request.getRemoteAddr()。但是如果通过了Apache,Nagix等反向代理软件则获取不到客户端的真实IP。
  • 经过代理以后,由于在客户端和服务之间增加了中间层,因此服务器无法直接拿到客户端的IP,服务器端应用也无法直接通过转发请求的地址返回给客户端。但是在转发请求的HTTP头信息中,增加了X-FORWARDED-FOR信息。用以跟踪原有的客户端IP地址和原来客户端请求的服务器地址。
  • 例如:使用反向代理,将http://192.168.10.1:8081的URL反向代理为http://example.com时,用 request.getRemoteAddr() 方法获取的IP地址是:127.0.0.1或192.168.10.1,而并不是客户端的真实IP。也就是说访问http://example.com,是经过代理服务器访问http://192.168.10.1:8081的,因此request.getRemoteAddr()获取的IP其实是代理服务器的IP。

获取方法

(1)方法一

public String getRemortIP(HttpServletRequest request) { 
  if (request.getHeader("x-forwarded-for") == null) { 
   return request.getRemoteAddr(); 
  } 
  return request.getHeader("x-forwarded-for"); 
 }

(2)方法二:squid.conf 的配制文件 forwarded_for 项默认是为on,如果 forwarded_for 设成了 off  则:X-Forwarded-For: unknown

//equalsIgnoreCase将字符串与指定的对象比较,不考虑大小写。
//isBlank 字符串为空、长度为0或由空白符组成
public String getIpAddr(HttpServletRequest request) { 
		String[] headers = ["x-forwarded-for","Proxy-Client-IP","WL-Proxy-Client-IP"]
       String ip = null;
       for(String header: headers){
           if(StringUtils.isBlank(addr) || "unknown".equalsIgnoreCase(ip)) { 
               ip = request.getHeader(header); 
           } 
      }
      if(StringUtils.isBlank(addr) || "unknown".equalsIgnoreCase(ip)) { 
           ip = request.getRemoteAddr(); 
       } 
       return ip; 
   }

(3)如果使用多级反向代理,X-Forwarded-For的值并不止一个,获取到的是一串IP值。

public static String getClientIP(HttpServletRequest request) {
		String[] headers = {"x-forwarded-for","Proxy-Client-IP","WL-Proxy-Client-IP"};
		String ip = null;
		for(String header: headers){
			if(StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
				ip = request.getHeader(header);
			}
		}
		if(StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
			if(ip.equals("127.0.0.1") || ip.equals("0:0:0:0:0:0:0:1")){
				//根据网卡取本机配置的IP
				InetAddress inet=null;
				try {
					inet = InetAddress.getLocalHost();
				} catch (UnknownHostException e) {
					e.printStackTrace();
				}
				ip= inet.getHostAddress();
			}
		}
		//if(ip.contains(","){
		if(StringUtils.isBlank(ip)){
			if(ip.indexOf(",")>0){
				ip= ip.substring(0,ip.indexOf(","));
			}
		}
		return ip;
	}

参考:GO GO

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值