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

Java 取得真實客戶端 IP:穿透反向代理與多層轉發的完整解法

     編輯:Java 相關知識

問題背景

當系統部署於 Nginx、Squid 等反向代理後方,request.getRemoteAddr() 僅能取得代理伺服器 IP,無法直接獲得用戶真實 IP。

HTTP 標頭傳遞機制

代理伺服器會在轉發請求時加入 X-Forwarded-For 標頭,格式為:client, proxy1, proxy2,第一個非 unknown 的 IP 即為真實客戶端。

方案一:簡易版(單層代理)

public String getRemoteIP(HttpServletRequest req) {
    String ip = req.getHeader("x-forwarded-for");
    return (ip == null) ? req.getRemoteAddr() : ip;
}

方案二:健壯版(多層代理、Squid 相容)

public String getRealIP(HttpServletRequest req) {
    String ip = req.getHeader("x-forwarded-for");
    if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
        ip = req.getHeader("Proxy-Client-IP");
    }
    if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
        ip = req.getHeader("WL-Proxy-Client-IP");
    }
    if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
        ip = req.getRemoteAddr();
    }
    // 多層代理取第一個有效 IP
    if (ip != null && ip.contains(",")) {
        for (String part : ip.split(",")) {
            part = part.trim();
            if (!"unknown".equalsIgnoreCase(part)) return part;
        }
    }
    return ip;
}

關鍵提醒

  • Squid forwarded_for off 會導致 X-Forwarded-For: unknown,需檢查代理設定。
  • 生產環境建議搭配信任代理 IP 白名單,防止標頭偽造攻擊。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved