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作为一个可靠指标

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/499861.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

kafka入门:简介、使用场景、设计原理、主要配置及集群搭建

本文转自&#xff1a;http://www.aboutyun.com/thread-9341-1-1.html一、入门1、简介Kafka is a distributed,partitioned,replicated commit logservice。它提供了类似于JMS的特性&#xff0c;但是在设计实现上完全不同&#xff0c;此外它并不是JMS规范的实现。kafka对消息保存…

git大小写解决

git大小写解决 git reset --hard head git的回退操作 git config --get core.ignorecase 查看git忽略大小写的状态&#xff0c;true就是忽略大小写&#xff0c;false就是不忽略大小写 git config core.ignorecase false 更改git为不忽略大小写 情景1&#xff1a;&#xff08;…

深入理解Hadoop集群和网络

云计算和Hadoop中网络是讨论得相对比较少的领域。本文原文由Dell企业技术专家Brad Hedlund撰写&#xff0c;他曾在思科工作多年&#xff0c;专长是数据中心、云网络等。文章素材基于作者自己的研究、实验和Cloudera的培训资料。 本文将着重于讨论Hadoop集群的体系结构和方法&am…

Method-Swizzling实战-实现iOS原生网络请求性能采集

一、方法交换实现步骤&#xff08;实例方法和类方法处理逻辑类似&#xff09; 1.检查原类&#xff08;要被替换方法的类&#xff09;的原实例方法是否存在&#xff0c;如果不存在&#xff0c;则不交换&#xff1b;2.检查新类&#xff08;最终被使用的方法所在的类&#xff09;的…

java8新特性(1)--- lambda表达式

java8新特性&#xff08;1&#xff09;— lambda表达式 函数式编程&#xff0c;简化开发 新增语法&#xff08;->&#xff09; package com.common.jdk8;// 试想&#xff0c;如果在jdk1.7中&#xff0c;我们要实现基于这个接口的加法运算&#xff0c;一般会这样 // 先创建…

iOS中WebKit框架应用与解析

一、引言 在iOS8之前&#xff0c;在应用中嵌入网页通常需要使用UIWebView这样一个类&#xff0c;这个类通过URL或者HTML文件来加载网页视图&#xff0c;功能十分有限&#xff0c;只能作为辅助嵌入原生应用程序中。虽然UIWebView也可以做原生与JavaScript交互的相关处理&#xf…

java8新特性(2)--- 方法引用

java8新特性&#xff08;2&#xff09;— 方法引用 新增语法双冒号&#xff08;::&#xff09; package com.common.jdk8;import java.util.Arrays; import java.util.List;//方法引用 public class Jdk8Test2 {public static void main(String[] args) {//构造器引用&#x…

让WKWebView支持NSURLProtocol

NSURLProtocol能够拦截UIWebView内所有的请求&#xff0c;但是WKWebView 中的请求却完全不遵从这一规则&#xff0c;只是象征性调用canInitWithRequest方法&#xff0c;之后的整个请求流程似乎就与 NSURLProtocol 完全无关了。使我一度认为WKWebView请求不遵守NSURLProtocol协议…

java8新特性(3)--- 函数式接口

java8新特性&#xff08;3&#xff09;— 函数式接口 有且仅有一个抽象方法 package com.common.jdk8;import java.util.Arrays; import java.util.List; import java.util.function.Predicate;// 函数式接口(Functional Interface)就是一个有且仅有一个抽象方法&#xff0c;…

Git仓库迁移,包括所有的分支、标签、日志

仅三行命令即可完成&#xff1a; git clone --bare http://域名/分组/仓库名称.git cd 仓库名称.git git push --mirror http://新域名/新分组/新仓库名称.git

java8新特性(4)— Stream流

java8新特性&#xff08;4&#xff09;— Stream流 遍历集合更强大 package com.common.jdk8;import java.util.*; import java.util.stream.Collectors;//Java 8 API添加了一个新的抽象称为流Stream&#xff0c;可以让你以一种声明的方式处理数据。 //Stream 使用一种类似用…

二、工作量证明链-区块链技术的雏形

用算法解决难题——区块链技术的雏形 构造出一个完美的、可以解决问题的“拜占庭容错系统”是一个不小的挑战。而且构造出来以后&#xff0c;其是否真的有效&#xff0c;能否经得起时间的考验与各方的质疑&#xff0c;这些都关乎着这个系统未来的命运与其创造群体的声誉。 2008…

CocoaPods通过网络代理执行资源更新

一、使用网络代理 首先在电脑设置网络代理配置。 二、设置git的http、https代理 1.查看git是否已经设置网络代理 首先可以先查本地的git配置有没有配置http/https代理&#xff1a;git config --global -e 如果没有看到 [http]proxy和 [https]proxy就代表没有设置http/http…

java8新特性(5)— Optional 类

java8新特性&#xff08;5&#xff09;— Optional 类 空指针解决方案 package com.common.jdk8;import java.util.Optional;//Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true&#xff0c;调用get()方法会返回该对象。 //Optional 是个容器&…

五、工作量证明链解决拜占庭将军问题之模拟程序(Objective-C)

一、概述&#xff1a; 此程序用来模拟工作量证明链如何解决拜占庭将军问题&#xff0c;使用Objective-C语言&#xff0c;需要使用Xcode开发工具运行并执行演示&#xff0c;演示结果打印在Xcode控制台。 二、示例程序&#xff1a; 程序下载地址&#xff1a;工作量证明链解决拜…

java8新特性(6)— 日期与时间

java8新特性&#xff08;6&#xff09;— 日期与时间 全新的日期与时间处理 package com.common.jdk8;import java.time.*;//Java 8通过发布新的Date-Time API (JSR 310)来进一步加强对日期与时间的处理。 //在旧版的 Java 中&#xff0c;日期时间 API 存在诸多问题&#xff…

六、区块链主流共识算法浅析

转自&#xff1a;http://www.cocoachina.com/cms/wap.php?actionarticle&id22240。 一、概述&#xff1a; 1.工作量证明&#xff08;Proof of Work&#xff09;&#xff1a; 通过所有节点的工作量竞争来达成一致。竞争的是运算力。 2.权益证明&#xff08;Proof of S…

java8新特性(7)— Base64

java8新特性&#xff08;7&#xff09;— Base64 新增Base64工具类 package com.common.jdk8;import java.io.UnsupportedEncodingException; import java.util.Base64; import java.util.UUID;//在Java 8中&#xff0c;Base64编码已经成为Java类库的标准。 //Java 8 内置了 …

修改git历史提交的commit信息

本文是基于idea的操作&#xff0c;亲测可用 前言&#xff1a; 很多公司都会自定义 Git - 使用强制策略&#xff0c;那么他的commit信息就会有固定的格式&#xff0c;一旦不是这个格式&#xff0c;就会出现push失败 但是push失败&#xff0c;很多也只在dev和master分支做强制限…

七、区块链如何运用merkle tree验证交易真实性

转载自&#xff1a;https://www.tangshuang.net/4117.html 本文假设你已经知道区块链中merkle tree的原理&#xff0c;现在搞明白具体怎么来实现交易真实性验证。 Merkle Tree 这个小节简述一下merkle的原理。简单说&#xff0c;merkle tree就是一个hash二叉树&#xff0c;父…