网站开发技术难点,公司网站建设 阜阳,教师可以做网站吗,大悟县城乡建设局网站java后端获取客户端真实ip#xff0c;原理#xff1a;
一般都是下面代码中的做法#xff1a;但很多人只知道这样能拿到#xff0c;稍微有改动就不知道怎么办了
看看网上的各种说法#xff0c;接下来容我一一讲解#xff0c;如有纰漏#xff0c;敬请指正。
public sta…java后端获取客户端真实ip原理
一般都是下面代码中的做法但很多人只知道这样能拿到稍微有改动就不知道怎么办了
看看网上的各种说法接下来容我一一讲解如有纰漏敬请指正。
public static String getIpAdrress(HttpServletRequest request) {String ip null;//X-Forwarded-ForSquid 服务代理String ipAddresses request.getHeader(X-Forwarded-For);System.out.println(ipAddresses:ipAddresses);EnumerationString headerNames request.getHeaderNames();while (headerNames.hasMoreElements()) {//打印所有头信息String s headerNames.nextElement();String header request.getHeader(s);System.out.println(s::::header);}System.out.println(headerNames:JSON.toJSONString(headerNames));System.out.println(RemoteHost:request.getRemoteHost());System.out.println(RemoteAddr:request.getRemoteAddr());String unknown unknown;if (ipAddresses null || ipAddresses.length() 0 || unknown.equalsIgnoreCase(ipAddresses)) {//Proxy-Client-IPapache 服务代理ipAddresses request.getHeader(Proxy-Client-IP);}if (ipAddresses null || ipAddresses.length() 0 || unknown.equalsIgnoreCase(ipAddresses)) {//WL-Proxy-Client-IPweblogic 服务代理ipAddresses request.getHeader(WL-Proxy-Client-IP);}if (ipAddresses null || ipAddresses.length() 0 || unknown.equalsIgnoreCase(ipAddresses)) {//HTTP_CLIENT_IP有些代理服务器ipAddresses request.getHeader(HTTP_CLIENT_IP);}if (ipAddresses null || ipAddresses.length() 0 || unknown.equalsIgnoreCase(ipAddresses)) {//X-Real-IPnginx服务代理ipAddresses request.getHeader(X-Real-IP);}//有些网络通过多层代理那么获取到的ip就会有多个一般都是通过逗号,分割开来并且第一个ip为客户端的真实IPif (ipAddresses ! null ipAddresses.length() ! 0) {ip ipAddresses.split(,)[0];}//还是不能获取到最后再通过request.getRemoteAddr();获取if (ip null || ip.length() 0 || unknown.equalsIgnoreCase(ipAddresses)) {ip request.getRemoteAddr();}return ip;}讲讲上面获取用户ip的代码
首先有个基本概念就是客户端要想和服务端交互就必须告诉服务端自己的ip毕竟有TCP三次握手。 当然这些都是普通用户特殊用户会隐藏ip这种暂且不说。 再从服务端说起如果服务器直接把IP暴漏出去那么request.getRemoteAddr()就能拿到客户端ip。
但目前流行的架构中基本上服务器都不会直接把自己的ip暴漏出去一般前面还有一层或多层反向代理常见的nginx居多。 加了代理后相当于服务器和客户端中间还有一层这时候request.getRemoteAddr()拿到的就是代理服务器的ip了并不是客户端的ip。所以这种情况下一般会在转发头上加X-Forwarded-For等信息用来跟踪原始客户端的ip。 这时候才会用上面的这些代码。解释下这些加上的信息
X-Forwarded-For
这是一个 Squid 开发的字段只有在通过了HTTP代理或者负载均衡服务器时才会添加该项。
格式为X-Forwarded-For:client1,proxy1,proxy2一般情况下第一个ip为客户端真实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一般用这个。总结
不知道你有没有发现上面这些头信息都是各做各的没有一个统一所以代码也就写成了这样其实就是一个一个试呗。
所以指不定以后再来个什么代理服务器头信息是XX-xx-xx那我们的代码也要做相应的修改。
还有这代码只是一个大概的思想具体情况具体对待因为获取不到请求头这些ip的情况也不在少数哪怕代理层以后都统一了用户层还有其他幺蛾子方法就是不让你知道他的ip所以总的结论就是上有政策下有对策。
举例几个常见的案例
1.服务端防刷 2.记录用户操作 等等总之就是服务端监控和区分客户端的经常会用ip作为一个可靠指标