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

request.getRemoteAddr() 與 getRemoteHost() 區別及獲取真實客戶端 IP 方案

     編輯:關於JSP

兩個方法的區別與常見坑

方法返回值典型場景
getRemoteAddr()客戶端IP 地址記錄訪問日誌、IP 限流
getRemoteHost()客戶端主機名(解析失敗時退回 IP)顯示主機名、內網環境識別

常見問題 1:本地測試返回 0:0:0:0:0:0:0:1

原因:IPv6 回環地址 ::1 的展開形式。解決:

  • 生產環境正常獲取 IPv4
  • 或在 Tomcat server.xml 配置 address="0.0.0.0" 強制 IPv4
  • 代碼層面兼容:ip.replace("0:0:0:0:0:0:0:1", "127.0.0.1")

常見問題 2:反向代理/負載均衡下獲取到代理 IP

當客戶端經過 Nginx、Apache、CDN 等中間層,getRemoteAddr() 返回的是代理服務器 IP。需讀取 HTTP 頭:

獲取真實 IP 通用工具方法

public static String getRealIp(HttpServletRequest request) {
    String ip = request.getHeader("X-Forwarded-For");
    if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
        ip = request.getHeader("Proxy-Client-IP");
    }
    if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
        ip = request.getHeader("WL-Proxy-Client-IP");
    }
    if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
        ip = request.getRemoteAddr();
    }
    // 多級代理取第一個非 unknown IP
    if (ip != null && ip.contains(",")) {
        String[] ips = ip.split(",");
        for (String s : ips) {
            if (!"unknown".equalsIgnoreCase(s.trim())) {
                return s.trim();
            }
        }
    }
    return ip;
}

關鍵點

  • X-Forwarded-For 格式:client, proxy1, proxy2,第一個非 unknown 為真實客戶端 IP
  • 需在反向代理層配置 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; (Nginx)
  • 防偽造:僅信任受信代理 IP 範圍內的請求頭
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved