1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > java后端获取客户端(用户)真实ip 原理

java后端获取客户端(用户)真实ip 原理

时间:2023-10-14 12:26:23

相关推荐

java后端获取客户端(用户)真实ip 原理

java后端获取客户端真实ip,原理:

一般都是下面代码中的做法:但很多人只知道这样能拿到,稍微有改动就不知道怎么办了
看看网上的各种说法,接下来容我一一讲解,如有纰漏,敬请指正。

public static String getIpAdrress(HttpServletRequest request) {String ip = null;//X-Forwarded-For:Squid 服务代理String ipAddresses = request.getHeader("X-Forwarded-For");System.out.println("====ipAddresses:"+ipAddresses);Enumeration<String> 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-IP:apache 服务代理ipAddresses = request.getHeader("Proxy-Client-IP");}if (ipAddresses == null || ipAddresses.length() == 0 || unknown.equalsIgnoreCase(ipAddresses)) {//WL-Proxy-Client-IP:weblogic 服务代理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-IP:nginx服务代理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作为一个可靠指标

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。