2018-09-25 如何取得wap和web用戶的真實(shí)IP

https://blog.csdn.net/rogerjava/article/details/9418211

HTTP_X_FORWARDED_FOR,

REMOTE_ADDR荒揣,

HTTP_CLIENT_IP

HTTP_VIA的區(qū)別總結(jié)

在移動(dòng)互聯(lián)網(wǎng)中烤咧,如何才能取得用戶真正的IP呢弧蝇,其實(shí)我們?cè)趆eader中可以得到的四個(gè)參數(shù)分別為REMOTE_ADDR 榛泛,HTTP_VIA 转晰,HTTP_X_FORWARDED_FOR 莲蜘,HTTP_CLIENT_IP熟呛,這四個(gè)參數(shù)意義如下:

REMOTE_ADDR - 是你的客戶端跟你的服務(wù)器“握手”時(shí)候的IP(訪問客戶端的 IP 地址)静檬。如果使用了“匿名代理”炭懊,REMOTE_ADDR將顯示代理服務(wù)器的IP,REMOTE_ADDR –訪問客戶端的 IP 地址拂檩,有可能是用戶的IP侮腹,也有可能是代理的IP。

HTTP_CLIENT_IP - 是代理服務(wù)器發(fā)送的HTTP頭稻励,代理端的IP父阻,可能存在,可偽造望抽。如果是“超級(jí)匿名代理”加矛,則返回none值。同樣煤篙,REMOTE_ADDR也會(huì)被替換為這個(gè)代理服務(wù)器的IP斟览。

HTTP_X_FORWARDED_FOR -簡(jiǎn)稱XFF頭,它代表客戶端辑奈,也就是HTTP的請(qǐng)求端真實(shí)的IP苛茂,只有在通過了HTTP 代理(比如APACHE代理)或者負(fù)載均衡服務(wù)器時(shí)才會(huì)添加該項(xiàng)。它不是RFC中定義的標(biāo)準(zhǔn)請(qǐng)求頭信息鸠窗,在squid緩存代理服務(wù)器開發(fā)文檔中可以找到該項(xiàng)的詳細(xì)介紹妓羊。如果有該條信息, 說明您使用了代理服務(wù)器,地址就是后面的數(shù)值稍计≡瓿瘢可以偽造。標(biāo)準(zhǔn)格式如下:X-Forwarded-For: client1, proxy1, proxy2

HTTP_VIA - 如果有該條信息, 就證明您使用了代理服務(wù)器,代理服務(wù)器的地址就是后面的數(shù)值。

1)沒有使用代理服務(wù)器的情況:

  REMOTE_ADDR = 您的 IP

  HTTP_VIA = 沒數(shù)值或不顯示

  HTTP_CLIENT_IP = 沒數(shù)值或不顯示

  HTTP_X_FORWARDED_FOR = 沒數(shù)值或不顯示

2)使用透明代理服務(wù)器的情況:TransparentProxies

  REMOTE_ADDR = 最后一個(gè)代理服務(wù)器 IP

  HTTP_VIA = 代理服務(wù)器 IP

  HTTP_CLIENT_IP = 代理服務(wù)器 IP

  HTTP_X_FORWARDED_FOR = 您的真實(shí) IP 涨颜,經(jīng)過多個(gè)代理服務(wù)器時(shí)费韭,這個(gè)值類似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。

這類代理服務(wù)器還是將您的信息轉(zhuǎn)發(fā)給您的訪問對(duì)象庭瑰,無法達(dá)到隱藏真實(shí)身份的目的星持。

3)使用普通匿名代理服務(wù)器的情況:AnonymousProxies

  REMOTE_ADDR = 最后一個(gè)代理服務(wù)器 IP

  HTTP_VIA = 代理服務(wù)器 IP

  HTTP_CLIENT_IP = 代理服務(wù)器 IP

  HTTP_X_FORWARDED_FOR = 代理服務(wù)器 IP ,經(jīng)過多個(gè)代理服務(wù)器時(shí)弹灭,這個(gè)值類似如下:203.98.182.163, 203.98.182.163, 203.129.72.215督暂。

隱藏了您的真實(shí)IP,但是向訪問對(duì)象透露了您是使用代理服務(wù)器訪問他們的穷吮。

4)使用欺騙性代理服務(wù)器的情況:DistortingProxies

  REMOTE_ADDR = 代理服務(wù)器 IP

  HTTP_VIA = 代理服務(wù)器 IP

  HTTP_CLIENT_IP = 代理服務(wù)器 IP

  HTTP_X_FORWARDED_FOR = 隨機(jī)的 IP 逻翁,經(jīng)過多個(gè)代理服務(wù)器時(shí),這個(gè)值類似如下:203.98.182.163, 203.98.182.163, 203.129.72.215捡鱼。

告訴了訪問對(duì)象您使用了代理服務(wù)器八回,但編造了一個(gè)虛假的隨機(jī)IP代替您的真實(shí)IP欺騙它。

5)使用高匿名代理服務(wù)器的情況:HighAnonymity Proxies (Elite proxies)

  REMOTE_ADDR = 代理服務(wù)器 IP

  HTTP_VIA = 沒數(shù)值或不顯示

  HTTP_CLIENT_IP = 沒數(shù)值或不顯示

  HTTP_X_FORWARDED_FOR = 沒數(shù)值或不顯示 驾诈,經(jīng)過多個(gè)代理服務(wù)器時(shí)缠诅,這個(gè)值類似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。

完全用代理服務(wù)器的信息替代了您的所有信息乍迄,就象您就是完全使用那臺(tái)代理服務(wù)器直接訪問對(duì)象管引。

6)使用了cdn內(nèi)容分發(fā)網(wǎng)絡(luò)

由于訪客不是直接訪問源服務(wù)器,跟源服務(wù)打交道的都是CDN的節(jié)點(diǎn)機(jī)器闯两,所以在源服務(wù)器抓取到的IP都是節(jié)點(diǎn)IP褥伴。這對(duì)按ip來統(tǒng)計(jì)的瀏覽量、網(wǎng)站統(tǒng)計(jì)等模塊的影響會(huì)比較大漾狼。一般來說重慢,CDN節(jié)點(diǎn)會(huì)以某種方式將源客戶端的IP傳遞給源服務(wù)器,就拿我用的網(wǎng)宿CDN來說邦投,它是將源IP添加到了一個(gè)叫“Cdn-Src-Ip”的Http Header里

注:Squid默認(rèn)設(shè)置forwarded_for項(xiàng)默認(rèn)是為on伤锚,如果 forwarded_for設(shè)成了 off 則:X-Forwarded-For: unknown

2 wap特有表頭屬性分析
Sky-Real-IP: Sky-Wapproxy的代理IP,是SKY WAP代理的請(qǐng)求

X-real-ip: 跟remote_addr一樣志衣,對(duì)nginx而言設(shè)置了則有不設(shè)置則無屯援,一般nginx設(shè)置為 proxy_set_header X-real-ip $remote_addr;

x-network-info GPRS,10.139.155.216,13951615696,211.139.172.70,unsecured,移動(dòng)的gprs網(wǎng)絡(luò)信息,10.139.155.216和211.139.172.70都是WAP網(wǎng)關(guān)的IP念脯,這次會(huì)話使用的是非安全的通信模式狞洋,即是沒有使用安全服務(wù)層(TLS或者WTLS),13951615696是你們省網(wǎng)關(guān)的GT碼

x-forwarded-for 10.139.155.216, 10.139.155.215 同HTTP_X_FORWARDED_FOR

x-source-id 連接模式绿店,一般是本地局域網(wǎng)IP

client-ip:終端的IP即終端上網(wǎng)時(shí)動(dòng)態(tài)分配的IP(clientip)有可能是內(nèi)網(wǎng)IP

clientip: 使用UCWEB時(shí)uc帶上的客戶端IP

3 關(guān)于Proxy-Client-IP和WL-Proxy-Client-IP
在apache+WebLogic整合系統(tǒng)中吉懊,apache會(huì)對(duì)request對(duì)象進(jìn)行再包裝庐橙,附加一些WLS要用的頭信息,兩個(gè)信息如下:

Proxy-Client-IP 代理客服端IP

WL-Proxy-Client-IP WebLogic代理客服端IP(weblogic設(shè)置了才會(huì)有這個(gè)參數(shù))

一般情況下Proxy-Client-IP和WL-Proxy-Client-IP的IP是一樣的

在Linux加Squid的組合做為代理服務(wù)器的網(wǎng)絡(luò)環(huán)境中借嗽,若Squid的配置forwarded_for 設(shè)成了 off則:X-Forwarded-For: unknown态鳖。此時(shí)在apache+WebLogic的系統(tǒng)中Proxy-Client-IP和WL-Proxy-Client-IP可以反應(yīng)出用戶的真實(shí)IP

4 如何取得用戶真實(shí)的IP
綜上所述:

正確的取得wap用戶IP的邏輯應(yīng)該是

  1.  判斷clientip是否為空,若不為空則取
    
  2.  判斷x-forwarded-for是否有值
    
  3.  若有值判斷是否是“unknown”若不是則此時(shí)用戶IP為x-forwarded-for中第一個(gè)不為unknown且不是當(dāng)前內(nèi)網(wǎng)的IP恶导。
    
  4.  若x-forwarded-for無值或?yàn)椤皍nknown”則看Proxy-Client-IP和WL-Proxy-Client-IP中是否有值浆竭,若有取此值,若無取REMOTE_ADDR作為用戶IP
    

流程圖如下:

下面是java代碼:

package com.ecom;
 
import org.apache.commons.lang3.StringUtils;
 
import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
/**
 * Created with IntelliJ IDEA.
 * User: R
 * Date: 13-8-1
 * Time: 上午11:34
 * To change this template use File | Settings | File Templates.
 */
public class RealIpUtils {
 
    /**
     * 取所有IP段的私有IP段
     * A類  私有地址  10.0.0.0---10.255.255.255  保留地址 127.0.0.0---127.255.255.255
     * B類  私有地址 172.16.0.0-172.31.255.255
     * C類  私有地址 192.168.0.0-192.168.255.255
     * D類  地址不分網(wǎng)絡(luò)地址和主機(jī)地址
     * E類  地址不分網(wǎng)絡(luò)地址和主機(jī)地址
     */
    private static long aBegin = getIpNum("10.0.0.0");
    private static long aEnd = getIpNum("10.255.255.255");
    private static long bBegin = getIpNum("172.16.0.0");
    private static long bEnd = getIpNum("172.31.255.255");
    private static long cBegin = getIpNum("192.168.0.0");
    private static long cEnd = getIpNum("192.168.255.255");
    private static long saveBegin = getIpNum("127.0.0.0");
    private static long saveEnd = getIpNum("127.255.255.255");
 
    //跟IP有關(guān)需要做判斷的header參數(shù)
    private static Set<String> ipHeaderNames = new HashSet<String>(){
        {
            add("clientip");//終端的IP即終端上網(wǎng)時(shí)動(dòng)態(tài)分配的IP
            add("x-forwarded-for");//簡(jiǎn)稱XFF頭惨寿,它代表客戶端邦泄,也就是HTTP的請(qǐng)求端真實(shí)的IP
            add("proxy-client-ip");//代理客服端IP
            add("wl-proxy-client-ip");//WebLogic代理客服端IP(weblogic設(shè)置了才會(huì)有這個(gè)參數(shù))
        }
    };
 
    public static String getRealIpAddr(HttpServletRequest request) {
 
        System.out.println("-------------getRealIpAddr start---------------------");
 
        //防止在header中的參數(shù)名有大小寫之分,重新將需要處理的參數(shù)值和內(nèi)容裝填入Map中
        Map<String,String> ipHeaders = new HashMap<String,String>();
        Enumeration<String> headerNames = request.getHeaderNames();
        StringBuilder headerNamesStr = new StringBuilder();
        while (headerNames.hasMoreElements()){
            String nowName = headerNames.nextElement();
            headerNamesStr.append(nowName+",");
            if(ipHeaderNames.contains(nowName.toLowerCase())){
                ipHeaders.put(nowName.toLowerCase(),request.getHeader(nowName));//裝填key和value
            }
        }
 
        System.out.println("headerNamesStr : "+headerNamesStr);
 
        //取正確的IP
        String ipAddress = null;
        ipAddress = ipHeaders.get("clientip");//取clientip與client-ip有區(qū)別
 
        System.out.println("clientip:"+ipAddress);
 
        if(ipAddress!=null&&isInnerIP(ipAddress)){//若取得的clientip是內(nèi)網(wǎng)IP裂垦,則置為0
            ipAddress = null;
        }
 
        //若clientip為空或者是內(nèi)網(wǎng)IP則取x-forwarded-for
        if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)){
            String xForwardedIpAddress = ipHeaders.get("x-forwarded-for");
            System.out.println("x-forwarded-for:"+ipAddress);
            //對(duì)于通過多個(gè)代理的情況顺囊,第一個(gè)IP為客戶端真實(shí)IP,多個(gè)IP按照','分割
            if (StringUtils.isNotEmpty(xForwardedIpAddress)) {
                String[] ipList = xForwardedIpAddress.split(",");
                for (String nowIp : ipList) {
                    if(isIpAddress(nowIp)&&!isInnerIP(nowIp)){//取第一個(gè)不是內(nèi)網(wǎng)IP的IP作為真實(shí)IP
                        ipAddress = nowIp;
                        break;
                    }
                }
            }
        }
 
        //若x-forwarded-for為空則取proxy-client-ip
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = ipHeaders.get("proxy-client-ip");
            System.out.println("proxy-client-ip:"+ipAddress);
        }
 
        //若proxy-client-ip為空則取wl-proxy-client-ip
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = ipHeaders.get("wl-proxy-client-ip");
            System.out.println("wl-proxy-client-ip:"+ipAddress);
        }
 
        //若wl-proxy-client-ip為空則取RemoteAddr
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getRemoteAddr();
            System.out.println("remote-addr:"+ipAddress);
            if (ipAddress.equals("127.0.0.1")) {
                //根據(jù)網(wǎng)卡取本機(jī)配置的IP
                InetAddress inet = null;
                try {
                    inet = InetAddress.getLocalHost();
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                }
                ipAddress = inet.getHostAddress();
            }
        }
 
        System.out.println("real-ip:"+ipAddress);
 
        System.out.println("-------------getRealIpAddr end---------------------");
 
        return ipAddress;
    }
 
 
    public static boolean isInnerIP(String ipAddress) {
        boolean isInnerIp = false;
        long ipNum = getIpNum(ipAddress);
        isInnerIp = isInner(ipNum, aBegin, aEnd) || isInner(ipNum, bBegin, bEnd) || isInner(ipNum, cBegin, cEnd) || isInner(ipNum, saveBegin, saveEnd);
        return isInnerIp;
    }
 
    private static long getIpNum(String ipAddress) {
        String[] ip = ipAddress.split("\\.");
        long a = Integer.parseInt(ip[0]);
        long b = Integer.parseInt(ip[1]);
        long c = Integer.parseInt(ip[2]);
        long d = Integer.parseInt(ip[3]);
 
        long ipNum = a * 256 * 256 * 256 + b * 256 * 256 + c * 256 + d;
        return ipNum;
    }
 
    private static boolean isInner(long userIp, long begin, long end) {
        return (userIp >= begin) && (userIp <= end);
    }
 
 
    /**
     * 檢驗(yàn)是否是合法的IP地址 * @param address String IP地址 * @return boolean IP地址是否合法
     */
    public static boolean isIpAddress(String address) {
        if(StringUtils.isEmpty(address)) return false;
        String regex = "(((2[0-4]d)|(25[0-5]))|(1d{2})|([1-9]d)|(d))[.](((2[0-4]d)|(25[0-5]))|(1d{2})|([1-9]d)|(d))[.]"
                + "(((2[0-4]d)|(25[0-5]))|(1d{2})|([1-9]d)|(d))[.](((2[0-4]d)|(25[0-5]))|(1d{2})|([1-9]d)|(d))";
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(address);
        return m.matches();
    }
}


本文來自 javaRoger 的CSDN 博客 ,全文地址請(qǐng)點(diǎn)擊:https://blog.csdn.net/rogerjava/article/details/9418211?utm_source=copy

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蕉拢,一起剝皮案震驚了整個(gè)濱河市特碳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌晕换,老刑警劉巖测萎,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異届巩,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)份乒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門恕汇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人或辖,你說我怎么就攤上這事瘾英。” “怎么了颂暇?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵缺谴,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我耳鸯,道長(zhǎng)湿蛔,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任县爬,我火速辦了婚禮阳啥,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘财喳。我一直安慰自己察迟,他們只是感情好斩狱,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著扎瓶,像睡著了一般所踊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上概荷,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天秕岛,我揣著相機(jī)與錄音,去河邊找鬼乍赫。 笑死瓣蛀,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的雷厂。 我是一名探鬼主播惋增,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼改鲫!你這毒婦竟也來了诈皿?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤像棘,失蹤者是張志新(化名)和其女友劉穎稽亏,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缕题,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡截歉,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了烟零。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瘪松。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖锨阿,靈堂內(nèi)的尸體忽然破棺而出宵睦,到底是詐尸還是另有隱情,我是刑警寧澤墅诡,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布壳嚎,位于F島的核電站,受9級(jí)特大地震影響末早,放射性物質(zhì)發(fā)生泄漏烟馅。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一荐吉、第九天 我趴在偏房一處隱蔽的房頂上張望焙糟。 院中可真熱鬧,春花似錦样屠、人聲如沸穿撮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)悦穿。三九已至攻礼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間栗柒,已是汗流浹背礁扮。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瞬沦,地道東北人太伊。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像逛钻,于是被迫代替她去往敵國(guó)和親僚焦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容