1. 程式人生 > 實用技巧 >獲取客戶端使用者真實ip方法整理(jekyll遷移)

獲取客戶端使用者真實ip方法整理(jekyll遷移)

layout: post
title: 獲取客戶端使用者真實ip方法整理
date: 2019-08-22
author: xiepl1997
tags: springboot

由請求獲取客戶端ip地址的方法是request.getRemoteAddr(),在大部分的情況下該方法是有效的,但是在通過了apache、squid等反向代理軟體就不能獲取到客戶端的真實ip了。

經過代理後,由於在客戶端和服務之間增加了中間層,因此伺服器無法直接拿取到使用者的ip地址,伺服器端應用也無法直接通過轉發請求的地址返回給客戶端。但在轉發請求的HTTP頭資訊中,增加了X-FORWARDED-FOR資訊,用以跟蹤原有客戶端ip地址和原來客戶端的請求的伺服器地址。

獲取客戶端真實ip地址的方法如下

/**
 * @param request
 * @return 返回使用者的IP地址
 */
public String getUserIp(HttpServletRequest request){
    String ip = request.getHeader("X-Forwarded-For");

    if(ip == null || ip.length() == 0 || "unknow".equalsIgnoreCase(ip)){
        ip = request.getHeader("Proxy-Client-IP");
    }
    if(ip == null || ip.length() == 0 || "unknow".equalsIgnoreCase(ip)){
        ip = request.getHeader("WL-Proxy-Client-IP");
    }
    if(ip == null || ip.length() == 0 || "unknow".equalsIgnoreCase(ip)){
        ip = request.getHeader("HTTP_CLIENT_IP");
    }
    if(ip == null || ip.length() == 0 || "unknow".equalsIgnoreCase(ip)){
        ip = request.getHeader("HTTP_X_FORWARDED_FOR");
    }
    if(ip == null || ip.length() == 0 || "unknow".equalsIgnoreCase(ip)){
        ip = request.getRemoteAddr();
    }

    return ip;
}

這些請求頭的意思:

  • X-Forwarded-For
    這是一個 Squid 開發的欄位,只有在通過了HTTP代理或者負載均衡伺服器時才會新增該項。
  • Proxy-Client-IP/WL- Proxy-Client-IP
    這個一般是經過apache http伺服器的請求才會有,用apache http做代理時一般會加上Proxy-Client-IP請求頭,而WL-Proxy-Client-IP是他的weblogic外掛加上的頭。
  • HTTP_CLIENT_IP
    有些代理伺服器會加上此請求頭。

(2019-08-24 補)
測試的時候因為用到自己電腦測試,於是用上訴方法會得到127.0.0.1的本地環回地址,為了獲取到本機的ip地址,加上以下程式碼

if(ip.equals("127.0.0.1")){
    //根據網絡卡獲取ip
    InetAddress inet = null;
    try {
        inet = InetAddress.getLocalHost();
    }catch (UnknownHostException e){
        e.printStackTrace();
    }
    ip = inet.getHostAddress();
}