需求背景
HTTP请求头中的Remote_Addr,X-Forwarded-For,X-Real-IP 我们在项目中有时需要获取请求端真实的IP,有时需要获取代理服务器的IP。 下面详细介绍如何获取。
一、Remote_Addr
Remote_Addr 表示发出请求的远程主机IP。remote_addr 代表客户端Ip,但它的值不是由客户端提供的,而是服务端根据客户端的ip指定的。 那我们如何理解这个呢?
情况 一:
当我们的使用A电脑浏览器访问网站时,假设中间没有任何代理,那么网站的web就会把remote_addr设置为A电脑的IP。
情况二:
如果使用了Nginx等代理,那么我们的浏览器会先访问这个代理,然后再由这个代理转发到网站,这样web服务器就会把remote_addr设置为这台代理机器的IP。(也就是Nginx所在的机器IP)。
java中获取Remote_Addr的api
通过HttpServletRequest来获取
String remoteAddr = request.getRemoteAddr();
二、X-Forwarded-For
X-Forwarded-For 代表客户端,也就是HTTP的请求端真实的IP,只有在通过了HTTP代理或者负载均衡服务器时才会添加该项。正如上面所说,当使用了代理时,web服务器就不知道你的真实IP了,为了避免这个情况,代理服务器通常会增加一个叫做X-Forwarded-For 的头信息,把连接它的客户端IP(即你的上网机器IP)加到这个头信息里,这样就能保证网站的web服务器能获取到真实IP。 格式一般为: X-Forwarded-For: 1.1.1.1,2.2.2.2,3.3.3.3 代表请求由1.1.1.1发出,这个第一个ip就是请求端真实IP。后面的都是代理层的IP。
java中获取X-Forwarded-For的api为
private static String getIpAddr(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
log.info("x-forwarded-for:"+ip);
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
log.info("Proxy-Client-IP:"+ip);
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
log.info("WL-Proxy-Client-IP:"+ip);
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
log.info("unknown:"+ip);
}
if (StringUtils.isNotEmpty(ip) &&
ip.indexOf(CharacterConst.SpecialSymbol.COMMA_SYMBOL) > 0) {
String[] str = ip.split(CharacterConst.SpecialSymbol.COMMA_SYMBOL);
ip = str[0];
log.info("ip:"+ip);
}
return ip;
}
|