Java之获取Nginx代理之后的客户端IP

Java之获取Nginx代理之后的客户端IP

Nginx代理接口之后,后台获取的IP地址都是127.0.0.1,解决办法是需要配置Nginx搭配后台获取的方法,获得设备的真实地址。我们想要获取的就是nginx代理日志中的这个IP
在这里插入图片描述

nginx配置

首先在nginx代理的对应location增加如下配置

#保留代理之前的host 包含客户端真实的域名和端口号
proxy_set_header    Host  $host; 
#保留代理之前的真实客户端ip
proxy_set_header    X-Real-IP  $remote_addr;  
#这个Header和X-Real-IP类似,但它在多级代理时会包含真实客户端及中间每个代理服务器的IP
proxy_set_header    X-Forwarded-For  $proxy_add_x_forwarded_for;
#表示客户端真实的协议(http还是https)
proxy_set_header X-Forwarded-Proto $scheme;

示例

server {
        listen       9010;
        server_name  127.0.0.1;

        location ^~  /tob_server/ {
            #代理地址
            proxy_pass http://127.0.0.1:9012/tob_server/;

            #保留代理之前的host 包含客户端真实的域名和端口号
			proxy_set_header    Host  $host; 
			#保留代理之前的真实客户端ip
			proxy_set_header    X-Real-IP  $remote_addr;  
			#这个Header和X-Real-IP类似,但它在多级代理时会包含真实客户端及中间每个代理服务器的IP
			proxy_set_header    X-Forwarded-For  $proxy_add_x_forwarded_for;
			#表示客户端真实的协议(http还是https)
			proxy_set_header X-Forwarded-Proto $scheme;

            #解决跨域
            add_header Access-Control-Allow-Origin *;
            #解决nginx转发丢失cookie的问题
            proxy_cookie_path /tob_server/ /;

            #解决options请求
            if ($request_method = 'OPTIONS') {
                add_header 'Access-Control-Max-Age' 1728000;
                add_header 'Content-Type' 'text/plain; charset=utf-8';
                add_header 'Content-Length' 0;
                return 204;
            }
         }

         location \ {
            root   html;
            index  index.html index.htm;
         }
         
         #解决代理异常
         error_page  404 500 502 503 504  /50x.html;
         location = /50x.html {
            root   html;
         }
}

java获取客户端IP

获取客户端IP地址工具类

public class IpUtils
{
    private static Logger logger = LoggerFactory.getLogger(IPUtils.class);
    
    /**
     * 获取客户端IP
     * 
     * @param request 请求对象
     * @return IP地址
     */
    public static String getIpAddr(HttpServletRequest request)
    {
        if (request == null)
        {
            return "unknown";
        }
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getHeader("X-Forwarded-For");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getHeader("X-Real-IP");
        }

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getRemoteAddr();
        }

        return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : getMultistageReverseProxyIp(ip);
    }

    /**
     * 从多级反向代理中获得第一个非unknown IP地址
     *
     * @param ip 获得的IP地址
     * @return 第一个非unknown IP地址
     */
    public static String getMultistageReverseProxyIp(String ip)
    {
        // 多级反向代理检测
        if (ip != null && ip.indexOf(",") > 0)
        {
            final String[] ips = ip.trim().split(",");
            for (String subIp : ips)
            {
                if (false == isUnknown(subIp))
                {
                    ip = subIp;
                    break;
                }
            }
        }
        return StringUtils.substring(ip, 0, 255);
    }

    /**
     * 检测给定字符串是否为未知,多用于检测HTTP请求相关
     *
     * @param checkString 被检测的字符串
     * @return 是否未知
     */
    public static boolean isUnknown(String checkString)
    {
        return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString);
    }
}

这样就可以通过代码获取到客户端的真实IP地址了。

参考文章:
https://blog.csdn.net/u012812482/article/details/126066550

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

opencv安装介绍以及基本图像处理详解

文章目录 一、什么是OpenCV ?二. OpenCV 安装1. 下载地址2.安装命令:pip install opencv-python 三、图像基础1. 基本概念2. 坐标系3. 基本操作(彩色图片)(1)读取图片:cv2.imread( )&#xff08…

ThreadLocal(3):ThreadLocal的内部结构

下面介绍ThreadLocal的内部结构,探究它能够实现线程数据隔离的原理。 1 常见的误解 ​如果我们不去看源代码的话,可能会猜测ThreadLocal是这样子设计的:每个ThreadLocal都创建一个Map,然后用线程作为Map的key,要存储…

this的指向问题总结

this一般会出现在函数里面,但是一般情况下只有在函数被调用执行时,才能确定this指向哪个对象。一般情况下this是指调用函数的对象。 1.在全局作用域下或者普通函数中this的指向一般都是window对象 window.fn(),普通函…

前端实现鼠标点击箭头旋转180度

效果&#xff1a; <div click"showChecklist" class"checkCLass cur pr-20px pl-20px pa flex ai-center"><span>{{ checkListStatus() }}</span><p class"trangle"></p></div> 下面是三角形状的样式 .tr…

qt对stl模型显示的封装

我一直都想把vtk显示这一块做成一个封装的静态lib&#xff0c;然后别的类只需要我暴露出的头文件和lib文件就可以了&#xff0c;这次我实现的是对一个放stl文件的文件夹下的stl文件做显示&#xff0c;用的是vs2017qt,实现的主要效果如下&#xff1a; 因为qt自身带的标题栏显示…

CAN_相关的测试用例+测试方法+测试工具使用+输出测试报告

测试类型: 第一:通信测试 第二:间接网络管理测试 第三:AUTOSAR网络管理测试 第四:诊断协议栈Diva测试 第五:诊断协议补充测试 第六:Bootloader测试 第七:网…

用html编写的招聘简历

用html编写的招聘简历 相关代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</tit…

架构师蓝图: 理解软件风格与模式

本文介绍了10种软件架构风格及其对应设计模式&#xff0c;梳理了各个风格的优缺点和适用场景&#xff0c;帮助读者在架构选项过程中能有的放矢&#xff0c;做出更适合业务场景的架构设计。原文: The Architect’s Blueprint: Understanding Software Styles and Patterns with …

onlyoffice document builder使用

office这个体系分为四个大教程 1、【document server文档服务器基础搭建】 2、【连接器(connector)或者jsApi调用操作office】-进阶 3、【document builder文档构造器使用】-进阶 4、【Conversion API(文档转化服务)】-进阶 如果需要连接器&#xff0c;可以查看&#xff1…

认识Redis:不只是缓存,还有这些厉害的功能!

在当今数据驱动的世界中&#xff0c;快速存取信息成为了技术发展的关键。而在众多存储解决方案中&#xff0c;Redis以其独特的魅力和强大的功能&#xff0c;成为了开发者们的宠儿。今天&#xff0c;就让我们一起来认识一下Redis。 一、Redis是什么&#xff0c;可以用来干什么&…

EasyRecovery易恢复中文破解版2024最新破解序列号

EasyRecovery易恢复是一款来自美国的数据恢复软件&#xff0c;已有35年&#xff08;或38年&#xff09;的历史。它支持不同存储介质的数据恢复&#xff0c;包括电脑系统硬盘、移动硬盘等&#xff0c;并针对不同的数据丢失原因提供了相应的恢复方案。 EasyRecovery易恢复是一款功…

【清关知识】毛里求斯的清关文件及清关手续

1、清关文件 1&#xff09;发票 海关发票&#xff08;3份&#xff09;、商业发票。所有货物随货发票必须为正本原始发票&#xff0c;所有进口商在办理清关提货手续时&#xff0c;首先必须向海关呈交商业登记号码&#xff0c;凭此登记号码才可向公司注册局登记。 2&#xff0…

【linux】体系结构和os管理

冯诺依曼体系结构 输入单元&#xff1a;包括键盘, 鼠标&#xff0c;扫描仪, 写板等 中央处理器(CPU)&#xff1a;含有运算器和控制器等 输出单元&#xff1a;显示器&#xff0c;打印机等 这里的存储器指的是内存 三者是相互连接的&#xff0c;设备之间会进行数据的来回拷贝&am…

以理论89、上机100分成绩终于通过了OceanBase OBCP的考试

OceanBase OBCP的考试分为理论考试和上机考试&#xff0c;跟OBCA认证考试比较来说&#xff0c;难度上升了一个很多大的层次。OBCA我是好几年前考的了&#xff0c;现在因为公司再去o&#xff0c;准备进OceanBase&#xff0c;所以必须快速考出OBCP证书&#xff0c;本来想着直接背…

【C#】使用代码实现龙年春晚扑克牌魔术(守岁共此时),流程描述篇

欢迎来到《小5讲堂》 大家好&#xff0c;我是全栈小5。 这是《C#》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对知识点的理解和掌握。…

【Java】图解 JVM 垃圾回收(二):垃圾收集器、Full GC

图解 JVM 垃圾回收&#xff08;二&#xff09; 1.垃圾收集器1.1 内存分配与回收策略1.2 Serial 收集器1.3 Parallel Scavenge 收集器1.4 ParNew 收集器1.5 CMS 收集器1.6 G1 收集器 2.Full GC 的触发条件 1.垃圾收集器 Java 虚拟机提供了多种垃圾回收器&#xff0c;每种回收器…

postgresql 文件结构(一) 数据库、表对应的文件

1、问题 甲方要求提供数据库数据量大小&#xff0c;由于各个业务数据库共用一个postgres&#xff0c;因此想把每个数据库占用的空间都统计一下。 2、查找物理存储文件目录 如下图所示&#xff0c;可以查询表、库的物理存储文件名称 -- 查询表对应的文件 select oid,relname…

c编译器学习02:chibicc文档翻译

目的 先粗略地看一遍作者的书籍。 原文档地址 https://www.sigbus.info/compilerbook# “低レイヤを知りたい人のためのCコンパイラ作成入門” 为想了解底层的人准备的C编译器制作入门 Rui Ueyama ruiucs.stanford.edu 2020-03-16 作者简介 https://www.sigbus.info/ 植山…

【前端素材】几款实用的后台管理系统html模板(附带源码)

一、需求分析 后台管理系统是一种用于管理网站、应用程序或系统的工具&#xff0c;它通常作为一个独立的后台界面存在&#xff0c;供管理员或特定用户使用。下面详细分析后台管理系统的定义和功能&#xff1a; 1. 定义 后台管理系统是一个用于管理和控制网站、应用程序或系统…

flink多流操作(connect cogroup union broadcast)

flink多流操作 1 分流操作2 connect连接操作2.1 connect 连接&#xff08;DataStream,DataStream→ConnectedStreams)2.2 coMap&#xff08;ConnectedStreams → DataStream&#xff09;2.3 coFlatMap&#xff08;ConnectedStreams → DataStream&#xff09; 3 union操作3.1 u…