Java获取客户端真实IP地址过程解析
这篇文章主要介绍了Java获取客户端真实IP地址过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 业务背景 服务器端接收客户端请求的时候,一般需要进行签名验证,客户端IP限定等拦截,在进行IP限定的时候就需要获取客户端真实的IP。 基础知识 访问服务端的方式一般分为两种: 未经过代理,直接访问服务器端; 通过多级代理,最终到达服务器端(nginx,squid,haproxy)。 客户端请求信息都包含在HttpServletRequest中,对于第一种访问方式可以通过getRemoteAddr()方法获得客户端真实IP,而另一种则行不通,但是可以通过x-forwarded-for获得转发后请求信息。当客户端请求被转发时,IP将会追加在其后并以英文逗号隔开,例如:10.47.103.13,4.2.2.2,10.96.112.230。 请求中的参数: request.getHeader("x-forwarded-for") : 10.47.103.13,10.96.112.230 request.getHeader("X-Real-IP") : 10.47.103.13 request.getRemoteAddr():10.96.112.230 客户端访问经过转发,IP将会追加在其后并以逗号隔开。最终准确的客户端信息为:
相关请求头的解释: X-Forwarded-For 记录一个请求从客户端出发到目标服务器过程中经历的代理,或者负载平衡设备的IP。这是由缓存代理软件 Squid 引入,用来表示 HTTP 请求端真实 IP,现在已经成为事实上的标准,被各大 HTTP 代理、负载均衡等转发服务广泛使用,并被写入 RFC 7239(Forwarded HTTP Extension)标准之中。格式为X-Forwarded-For:client1,proxy1,proxy2,一般情况下,第一个ip为客户端真实ip,后面的为经过的代理服务器的ip。现在大部分的代理都会加上这个请求头。 Proxy-Client-IP/WL- Proxy-Client-IP 这个一般是经过apache http服务器的请求才会有,用apache http做代理时一般会加上Proxy-Client-IP请求头,而WL-Proxy-Client-IP是他的weblogic插件加上的头。 HTTP_CLIENT_IP 有些代理服务器会加上此请求头。 X-Real-IP nginx代理一般会加上此请求头。 获取客户端真实IP地址 源码: /** * 获取客户端的IP地址<br/> * 注意本地测试访问项目地址时,浏览器请求不要用 localhost,请用本机IP;否则,取不到 IP * * @author east7 * @date 2019年12月03日 * @return String 真实IP地址 */ public static String getClientIpAddress(HttpServletRequest request) { // 获取请求主机IP地址,如果通过代理进来,则透过防火墙获取真实IP地址 String headerName = "x-forwarded-for"; String ip = request.getHeader(headerName); if (null != ip && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) { // 多次反向代理后会有多个IP值,第一个IP才是真实IP,它们按照英文逗号','分割 if (ip.indexOf(",") != -1) { ip = ip.split(",")[0]; } } if (checkIp(ip)) { headerName = "Proxy-Client-IP"; ip = request.getHeader(headerName); } if (checkIp(ip)) { headerName = "WL-Proxy-Client-IP"; ip = request.getHeader(headerName); } if (checkIp(ip)) { headerName = "HTTP_CLIENT_IP"; ip = request.getHeader(headerName); } if (checkIp(ip)) { headerName = "HTTP_X_FORWARDED_FOR"; ip = request.getHeader(headerName); } if (checkIp(ip)) { headerName = "X-Real-IP"; ip = request.getHeader(headerName); } if (checkIp(ip)) { headerName = "remote addr"; ip = request.getRemoteAddr(); // 127.0.0.1 ipv4,0:0:0:0:0:0:0:1 ipv6 if ("127.0.0.1".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip)) { //根据网卡取本机配置的IP InetAddress inet = null; try { inet = InetAddress.getLocalHost(); } catch (UnknownHostException e) { e.printStackTrace(); } ip = inet.getHostAddress(); } } logger.info("getClientIp IP is " + ip + ",headerName = " + headerName); return ip; } private static boolean checkIp(String ip) { if (null == ip || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { return true; } return false; } 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- java – 警告:[rawtypes]找到原始类型:Default
- java.lang.IllegalStateException: Duplicate ke
- `java(0%2!= 0)== false`
- 在java中访问继承的类变量
- java – 迭代每个可能的double值
- Java (JVM) Memory Model – Memory Management
- WinForms多线程数据绑定场景,最佳做法?
- java – 直接从存储库加载Drools/KIE Workbench工
- SpringCloud之Feign示例详解
- java – Hibernate:无法访问TransactionManager