• 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容器中,也是通用的。

  • 相关阅读:
    PyScript 使用(1)
    振兴二线城市,输送一线it人员
    devops部署过慢
    Masked Language Modeling Maybe Helpful for Prompt learning Testing ?
    E 2022.4.4 2
    Kaggle踩坑记
    Go从入门到精通——示例:并发打印
    Go从入门到精通——示例:Telnet 回音服务器——TCP服务器的基本结构
    Go从入门到精通—示例:模拟远程过程调用(RPC)
    Kubernetes——centos8.0 使用kubeadm部署 k8sv1.18.20+etcdv3.3.10+flannelv0.10.0 高可用集群
  • 原文地址:https://www.cnblogs.com/lori/p/15827010.html
Copyright © 2020-2023  润新知