• springboot~容器化环境获取真实IP地址


    首先,后端项目springboot,前端项目VUE,两个都是运行在docker容器里,通过k8s进行编排的。

    获取真实的客户端IP地址

    一 需要在前端VUE的宿主nginx中,添加请求头规则

    location /api {
    			proxy_set_header Host $http_host;
    			proxy_set_header X-Real-IP $remote_addr;
    			proxy_set_header REMOTE-HOST $remote_addr;
    			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    			proxy_pass http://localhost:8080/;
    }
    
    

    二 分享springboot下面获取IP地址方法

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.util.StringUtils;
    
    import javax.servlet.http.HttpServletRequest;
    import java.net.InetAddress;
    import java.net.UnknownHostException;
    
    
    /**
     * Ip地址
     *
     */
    public class IpUtils {
      private static Logger logger = LoggerFactory.getLogger(IpUtils.class);
      private static final String IP_UTILS_FLAG = ",";
      private static final String UNKNOWN = "unknown";
      private static final String LOCALHOST_IP = "0:0:0:0:0:0:0:1";
      private static final String LOCALHOST_IP1 = "127.0.0.1";
    
      /**
       * 获取IP公网地址
       * <p>
       * 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
       * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
       */
      public static String getIpAddr(HttpServletRequest request) {
        String ip = null;
        try {
          //以下两个获取在k8s中,将真实的客户端IP,放到了x-Original-Forwarded-For。而将WAF的回源地址放到了 x-Forwarded-For了。
          ip = request.getHeader("X-Original-Forwarded-For");
          if (StringUtils.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Forwarded-For");
          }
          //获取nginx等代理的ip
          if (StringUtils.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader("x-forwarded-for");
          }
          if (StringUtils.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
          }
          if (StringUtils.isEmpty(ip) || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
          }
          if (StringUtils.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
          }
          if (StringUtils.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
          }
          //兼容k8s集群获取ip
          if (StringUtils.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
            if (LOCALHOST_IP1.equalsIgnoreCase(ip) || LOCALHOST_IP.equalsIgnoreCase(ip)) {
              //根据网卡取本机配置的IP
              InetAddress iNet = null;
              try {
                iNet = InetAddress.getLocalHost();
              } catch (UnknownHostException e) {
                logger.error("getClientIp error: {}", e);
              }
              ip = iNet.getHostAddress();
            }
          }
        } catch (Exception e) {
          logger.error("IPUtils ERROR ", e);
        }
        //使用代理,则获取第一个IP地址
        if (!StringUtils.isEmpty(ip) && ip.indexOf(IP_UTILS_FLAG) > 0) {
          ip = ip.substring(0, ip.indexOf(IP_UTILS_FLAG));
        }
    
        return ip;
      }
    
    }
    

    上面方法在k8s容器中,也是通用的。

  • 相关阅读:
    Java 入门 9 Random 类 随机数
    Java 入门16 面向对象实现之前的小案例购物车
    Java 入门10 java的内存分配,数组内存图( 方法区 栈内存 堆内存)
    JAVA 12 联系回顾之前知识
    Java 13 面向对象的编程 小案例 实现购物车
    面试泛型
    面试反射
    从HashMap的执行流程开始 揭开HashMap底层实现
    面试什么是面向对象?面向对象三大特性?
    面试JMM内存模型
  • 原文地址:https://www.cnblogs.com/lori/p/15827010.html
Copyright © 2020-2023  润新知