• 如何根据HttpServletRequets获取用户真实IP地址


      最近的一个项目的某个功能获取用户的ip地址,添加用户的系统使用记录。

      我发现当我直接使用getRemoteAddr()方法从HttpServletRequet中获取用户的ip时,获取到的是服务器的ip地址,为什么会这样呢?


    网上找到的答案

        “当我们通过request获取客户端IP时,自身服务器通常会为了保护信息或者负载均衡的目的,对自身服务器做反向代理。此时如果我们通过request.getRemoteAddr();可能获取到的是自身代理服务器的IP,而无法达到获取用户请求ip的目的。


    最终的解决方案

      以下整理了各个代理服务器自己开发的转发服务请求头,这些请求头都不是标准的http请求头,不一定所有的代理都会带上这些请求头,所以通过这方式只能尽可能的获取到真实ip,但不能保证一定可以获取到真实ip,而且代理服务器请求头中获取的ip是可伪造的。

    参数:

    nginx服务代理 X-Real-IP
    Squid 服务代理 X-Forwarded-For
    apache 服务代理 Proxy-Client-IP
    weblogic 服务代理 WL-Proxy-Client-IP
    有些代理服务器 HTTP_CLIENT_IP

    以下是获取用户真实ip的工具类:

    package com.pantech.boot.common.systemlog.util;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import javax.servlet.http.HttpServletRequest;
    
    /**
     * @author 肖政宇
     * @date 2019-10-29 13:41
     * 说明:客户端ip地址相关操作
     */
    @Component
    public class IpAddress {
    
        @Autowired
        HttpServletRequest request;
    
        /**
         * 获取发送请求的客户端的ip地址
         *
         * @param request - 请求头
         * @return - ip地址
         */
        public String getIpAddress(HttpServletRequest request) {
            String ip = null;
    
            //X-Forwarded-For:Squid 服务代理
            String ipAddresses = request.getHeader("X-Forwarded-For");
    
            //X-Real-IP:nginx服务代理
            if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
                ipAddresses = request.getHeader("X-Real-IP");
            }
    
            //Proxy-Client-IP:apache 服务代理
            if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
                ipAddresses = request.getHeader("Proxy-Client-IP");
            }
    
            //WL-Proxy-Client-IP:weblogic 服务代理
            if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
                ipAddresses = request.getHeader("WL-Proxy-Client-IP");
            }
    
            //HTTP_CLIENT_IP:有些代理服务器
            if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
                ipAddresses = request.getHeader("HTTP_CLIENT_IP");
            }
    
            //有些网络通过多层代理,那么获取到的ip就会有多个,一般都是通过逗号(,)分割开来,并且第一个ip为客户端的真实IP
            if (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;
        }
    
        public String getIpAddress() {
            return getIpAddress(request);
        }
    }

    文中提到的解决方案原文地址:https://www.cnblogs.com/Mauno/p/Mauno.html

  • 相关阅读:
    linux系统判断内存是否达到瓶颈的小技巧
    利用tcpdump命令统计http的GET和POST请求
    tcpdump 基于mac地址抓取数据包
    使用liunx系统自带的工具sar监控指定接口速率
    Windows 环境搭建Redis集群
    Windows下RabbitMQ安装,部署,配置
    鼠标事件(二)
    鼠标事件(一)
    响应式web之媒体查询(一)
    UI事件之unload、resize和scroll
  • 原文地址:https://www.cnblogs.com/XiaoZhengYu/p/11766127.html
Copyright © 2020-2023  润新知