首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 獲取客戶端真實 IP 地址(支援代理、負載均衡環境)

     編輯:Java 相關知識

在生產環境中,應用常部署在 Nginx、Apache 等反向代理或負載均衡器後端,直接使用 request.getRemoteAddr() 只能獲取到代理服務器的 IP。本文提供一個健壯的工具方法,能夠穿透多層代理獲取用戶真實 IP。

核心實現

/**
 * 獲取客戶端真實 IP(支援公網、局域網、多級代理)
 * @param request HttpServletRequest 對象
 * @return 客戶端 IP 地址
 * @throws Exception 請求對象為空時拋出
 */
public static String getIpAddr(HttpServletRequest request) throws Exception {
    if (request == null) {
        throw new Exception("HttpServletRequest 對象不能為空");
    }

    String ip = request.getHeader("x-forwarded-for");
    if (isInvalidIp(ip)) {
        ip = request.getHeader("Proxy-Client-IP");
    }
    if (isInvalidIp(ip)) {
        ip = request.getHeader("WL-Proxy-Client-IP");
    }
    if (isInvalidIp(ip)) {
        ip = request.getRemoteAddr();
    }

    // 多級代理情況下,取第一個非 unknown 的 IP
    if (ip != null && ip.contains(",")) {
        String[] ips = ip.split("\\s*,\\s*");
        for (String candidate : ips) {
            if (!isInvalidIp(candidate)) {
                ip = candidate;
                break;
            }
        }
    }
    return ip;
}

private static boolean isInvalidIp(String ip) {
    return ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip);
}

關鍵點解析

Header來源適用場景
x-forwarded-for標準代理頭,格式:client, proxy1, proxy2Nginx、Apache、CDN、AWS ALB 等
Proxy-Client-IPApache HTTP Client / Squid 代理內部服務調用鏈
WL-Proxy-Client-IPWebLogic 代理WebLogic 集群環境
getRemoteAddr()Servlet 容器直接連接無代理、直連環境

安全提示

  • 防偽造: x-forwarded-for 可被客戶端偽造,關鍵業務(如風控、限流)應配合代理服務器配置,只信任可信代理添加的頭
  • IPv6 支援: 現代環境需考慮 IPv6 格式(如 ::ffff:192.168.1.1),可增加處理邏輯
  • 內網穿透: 獲取到內網 IP(10.x、172.16-31.x、192.168.x)時,可能需結合業務判斷是否繼續向前查找

Spring Boot 整合建議

可封裝為 RequestContextHolder 獲取請求的工具類,或通過 HandlerInterceptor 統一放入 ThreadLocal 供業務使用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved