如何取得wap和web用戶的真實IP

1 HTTP_X_FORWARDED_FOR, REMOTE_ADDR椭坚,HTTP_CLIENT_IP和HTTP_VIA的區(qū)別總結(jié)
在移動互聯(lián)網(wǎng)中碍舍,如何才能取得用戶真正的IP呢凳寺,其實我們在header中可以得到的四個參數(shù)分別為REMOTE_ADDR 捧颅,HTTP_VIA 盒卸,HTTP_X_FORWARDED_FOR ,HTTP_CLIENT_IP结执,這四個參數(shù)意義如下:

REMOTE_ADDR - 是你的客戶端跟你的服務(wù)器“握手”時候的IP(訪問客戶端的 IP 地址)度陆。如果使用了“匿名代理”,REMOTE_ADDR將顯示代理服務(wù)器的IP献幔,REMOTE_ADDR –訪問客戶端的 IP 地址懂傀,有可能是用戶的IP,也有可能是代理的IP蜡感。

HTTP_CLIENT_IP - 是代理服務(wù)器發(fā)送的HTTP頭蹬蚁,代理端的IP,可能存在郑兴,可偽造犀斋。如果是“超級匿名代理”,則返回none值杈笔。同樣闪水,REMOTE_ADDR也會被替換為這個代理服務(wù)器的IP。

HTTP_X_FORWARDED_FOR -簡稱XFF頭蒙具,它代表客戶端球榆,也就是HTTP的請求端真實的IP,只有在通過了HTTP 代理(比如APACHE代理)或者負載均衡服務(wù)器時才會添加該項禁筏。它不是RFC中定義的標準請求頭信息持钉,在squid緩存代理服務(wù)器開發(fā)文檔中可以找到該項的詳細介紹。如果有該條信息, 說明您使用了代理服務(wù)器篱昔,地址就是后面的數(shù)值每强。可以偽造州刽。標準格式如下: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 = 最后一個代理服務(wù)器 IP

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

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

  HTTP_X_FORWARDED_FOR = 您的真實 IP ,經(jīng)過多個代理服務(wù)器時穗椅,這個值類似如下:203.98.182.163, 203.98.182.163, 203.129.72.215辨绊。

這類代理服務(wù)器還是將您的信息轉(zhuǎn)發(fā)給您的訪問對象,無法達到隱藏真實身份的目的匹表。

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

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

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

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

  HTTP_X_FORWARDED_FOR = 代理服務(wù)器 IP 门坷,經(jīng)過多個代理服務(wù)器時宣鄙,這個值類似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。

隱藏了您的真實IP默蚌,但是向訪問對象透露了您是使用代理服務(wù)器訪問他們的冻晤。

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

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

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

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

  HTTP_X_FORWARDED_FOR = 隨機的 IP ,經(jīng)過多個代理服務(wù)器時绸吸,這個值類似如下:203.98.182.163, 203.98.182.163, 203.129.72.215鼻弧。

告訴了訪問對象您使用了代理服務(wù)器,但編造了一個虛假的隨機IP代替您的真實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)過多個代理服務(wù)器時绣硝,這個值類似如下:203.98.182.163, 203.98.182.163, 203.129.72.215蜻势。

完全用代理服務(wù)器的信息替代了您的所有信息,就象您就是完全使用那臺代理服務(wù)器直接訪問對象鹉胖。

注:Squid默認設(shè)置forwarded_for項默認是為on握玛,如果 forwarded_for設(shè)成了 off 則:X-Forwarded-For: unknown

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

X-real-ip: 跟remote_addr一樣,對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,移動的gprs網(wǎng)絡(luò)信息剃斧,10.139.155.216和211.139.172.70都是WAP網(wǎng)關(guān)的IP略板,這次會話使用的是非安全的通信模式,即是沒有使用安全服務(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)時動態(tài)分配的IP(clientip)有可能是內(nèi)網(wǎng)IP

clientip: 使用UCWEB時uc帶上的客戶端IP

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

Proxy-Client-IP 代理客服端IP

WL-Proxy-Client-IP WebLogic代理客服端IP(weblogic設(shè)置了才會有這個參數(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脯宿。此時在apache+WebLogic的系統(tǒng)中Proxy-Client-IP和WL-Proxy-Client-IP可以反應出用戶的真實IP

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

正確的取得wap用戶IP的邏輯應該是

  1.  判斷clientip是否為空,若不為空則取
    
  2.  判斷x-forwarded-for是否有值
    
  3.  若有值判斷是否是“unknown”若不是則此時用戶IP為x-forwarded-for中第一個不為unknown且不是當前內(nèi)網(wǎng)的IP泉粉。
    
  4.  若x-forwarded-for無值或為“unknown”則看Proxy-Client-IP和WL-Proxy-Client-IP中是否有值连霉,若有取此值,若無取REMOTE_ADDR作為用戶IP
    

流程圖如下:
[圖片上傳中嗡靡。跺撼。。(1)]

下面是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ò)地址和主機地址
    • E類 地址不分網(wǎng)絡(luò)地址和主機地址
      */
      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)時動態(tài)分配的IP
    add("x-forwarded-for");//簡稱XFF頭讨彼,它代表客戶端歉井,也就是HTTP的請求端真實的IP
    add("proxy-client-ip");//代理客服端IP
    add("wl-proxy-client-ip");//WebLogic代理客服端IP(weblogic設(shè)置了才會有這個參數(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);
          //對于通過多個代理的情況酣难,第一個IP為客戶端真實IP,多個IP按照','分割
          if (StringUtils.isNotEmpty(xForwardedIpAddress)) {
              String[] ipList = xForwardedIpAddress.split(",");
              for (String nowIp : ipList) {
                  if(isIpAddress(nowIp)&&!isInnerIP(nowIp)){//取第一個不是內(nèi)網(wǎng)IP的IP作為真實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)卡取本機配置的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);
}


/**
 * 檢驗是否是合法的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();
}

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末谍夭,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子憨募,更是在濱河造成了極大的恐慌紧索,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件菜谣,死亡現(xiàn)場離奇詭異珠漂,居然都是意外死亡,警方通過查閱死者的電腦和手機尾膊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門媳危,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人冈敛,你說我怎么就攤上這事待笑。” “怎么了抓谴?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵暮蹂,是天一觀的道長。 經(jīng)常有香客問我癌压,道長仰泻,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任滩届,我火速辦了婚禮集侯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘帜消。我一直安慰自己棠枉,他們只是感情好,可當我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布券犁。 她就那樣靜靜地躺著术健,像睡著了一般。 火紅的嫁衣襯著肌膚如雪粘衬。 梳的紋絲不亂的頭發(fā)上荞估,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天,我揣著相機與錄音稚新,去河邊找鬼勘伺。 笑死,一個胖子當著我的面吹牛褂删,可吹牛的內(nèi)容都是我干的飞醉。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼缅帘!你這毒婦竟也來了轴术?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤钦无,失蹤者是張志新(化名)和其女友劉穎逗栽,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體失暂,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡彼宠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了弟塞。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片凭峡。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖决记,靈堂內(nèi)的尸體忽然破棺而出摧冀,到底是詐尸還是另有隱情,我是刑警寧澤霉涨,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布按价,位于F島的核電站惭适,受9級特大地震影響笙瑟,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜癞志,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一往枷、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧凄杯,春花似錦错洁、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至膊存,卻和暖如春导而,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背隔崎。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工今艺, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人爵卒。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓虚缎,卻偏偏與公主長得像,于是被迫代替她去往敵國和親钓株。 傳聞我的和親對象是個殘疾皇子实牡,可洞房花燭夜當晚...
    茶點故事閱讀 42,877評論 2 345

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