1. 程式人生 > >ASP.NET獲取客戶端IP地址相關方法

ASP.NET獲取客戶端IP地址相關方法



因為要在專案中取到客戶端IP,在網上搜了下相關資料,找到一些方法,因為資料很多,經過比較對比後總結出來的,在下面列舉出來,方便以後查閱之用:


通常我們都通過下面的程式碼獲得IP:

string ip =System.Web.HttpContext.Current.Request.UserHostAddress;
string ip =System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];


注意:

       在ASP中使用 Request.ServerVariables("REMOTE_ADDR") 來取得客戶端的IP地址,但如果客戶端是使用代理伺服器來訪問,那取到的就是的代理伺服器IP地址,而不是真正的客戶端IP地址。要想透過取得客戶端的真實IP地址,就要使用 Request.ServerVariables("HTTP_X_FORWARDED_FOR") 來讀取。不過要注意的事,並不是每個代理伺服器都能用 Request.ServerVariables("HTTP_X_FORWARDED_FOR") 來讀取客戶端的真實 IP,有些用此方法讀取到的仍然是代理伺服器的IP。

      還有一點需要注意的是:如果客戶端沒有通過代理伺服器來訪問,那麼用 Request.ServerVariables ("HTTP_X_FORWARDED_FOR") 取到的值將是空的。因此,如果要在程式中使用此方法,可以這樣處理:即:如果客戶端通過代理伺服器,則取 HTTP_X_FORWARDED_FOR 的值,如果沒通過代理伺服器,就取 REMOTE_ADDR 的值。通用函式:如果不能取客戶端真實IP,就會取客戶端的代理 !!!


下面詳細介紹:

REMOTE_ADDR 說明:

訪問客戶端的 IP 地址。
此項資訊使用者不可以修改。
如果真的給改了的話,你也和伺服器連線不了了,伺服器就是按照這個來與客戶端建立連線並進行通訊的。實際我測試修改這個 ServerVariables , 一點效果都沒有。仍然獲得是實際的值。

但如果使用者使用了代理伺服器,上述程式碼獲得的是代理伺服器的IP地址;如果使用者使用了多個代理伺服器,則是到達伺服器的最後一個代理伺服器的IP地址。

如何繞過代理伺服器獲得使用者真實的IP地址呢?

方法一:

/// <summary>
        /// 取得客戶端真實IP。
        /// </summary>
        private static string GetUserIP_Two()
        {
            if (System.Web.HttpContext.Current.Request.ServerVariables["HTTP_VIA"] != null)
                return System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"].Split(new char[] { ',' })[0];
            else
                return System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
        }
    

方法二:

/// <summary>
        /// 取得客戶端真實IP。如果有代理則取第一個非內網地址
        /// </summary>			
        public static string GetUserIP_One()
        {
            var svrVar = HttpContext.Current.Request.ServerVariables;
            string result = svrVar["HTTP_X_FORWARDED_FOR"];

            if (!String.IsNullOrEmpty(result))
            {
                //可能有代理
                if (result.IndexOf(".") == -1)    //沒有".",非 IPv4 格式
                    result = null;
                else
                {
                    if (result.IndexOf(",") != -1)
                    {
                        //有",",估計多個代理。取第一個不是內網的IP。
                        result = result.Replace(" ", "");
                        string[] temparyip = result.Split(',', ';');
                        foreach (string ip in temparyip)
                        {
                            string tmp = ip.Substring(0, 7);
                            if (IsIP(ip) && ip.Substring(0, 3) != "10." && tmp != "192.168" && tmp != "172.16.")
                            {
                                result = ip;
                                break;
                            }
                        }
                    }
                    else if (!IsIP(result))
                        result = null;
                }
            }

            if (String.IsNullOrEmpty(result))
            {
                result = svrVar["REMOTE_ADDR"];
                if (String.IsNullOrEmpty(result))
                    result = HttpContext.Current.Request.UserHostAddress;
            }

            return result;
        }

/// <summary>
        /// ip驗證
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        private static bool IsIP(string ip)
        {
            string[] sections = ip.Split('.');
            if (sections.Length != 4)
                return false;

            foreach (string s in sections)
            {
                int tmp = int.Parse(s.Trim());
                if (tmp > 255)
                    return false;
            }
            return true;
        }     

Request.ServerVariables["HTTP_VIA"] ,ServerVariables["HTTP_X_FORWARDED_FOR"],Request.ServerVariables["REMOTE_ADDR"]的值分下面幾種情況:

一、沒有使用代理伺服器的情況:

      REMOTE_ADDR = 使用者的 IP
      HTTP_VIA = 沒數值或不顯示
      HTTP_X_FORWARDED_FOR = 沒數值或不顯示

二、使用透明代理伺服器的情況:Transparent Proxies

      REMOTE_ADDR = 最後一個代理伺服器 IP
      HTTP_VIA = 代理伺服器 IP
      HTTP_X_FORWARDED_FOR = 使用者的真實 IP ,經過多個代理伺服器時,這個值類似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。

   這類代理伺服器還是將您的資訊轉發給您的訪問物件,無法達到隱藏真實身份的目的。

三、使用普通匿名代理伺服器的情況:Anonymous Proxies

      REMOTE_ADDR = 最後一個代理伺服器 IP
      HTTP_VIA = 代理伺服器 IP
      HTTP_X_FORWARDED_FOR = 代理伺服器 IP ,經過多個代理伺服器時,這個值類似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。

   隱藏了您的真實IP,但是向訪問物件透露了您是使用代理伺服器訪問他們的。

四、使用欺騙性代理伺服器的情況:Distorting Proxies

      REMOTE_ADDR = 代理伺服器 IP
      HTTP_VIA = 代理伺服器 IP
      HTTP_X_FORWARDED_FOR = 隨機的 IP ,經過多個代理伺服器時,這個值類似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。

   告訴了訪問物件您使用了代理伺服器,但編造了一個虛假的隨機IP代替您的真實IP欺騙它。

所以getIp()也不是最好的,因為可以編造一個假的IP,具體做法去看http://www.cnblogs.com/kingthy/archive/2007/11/24/970783.html

總結:
"Request.UserHostAddress"是可信的.但是這樣的話卻又獲取不了那些已使用了代理伺服器的使用者真實IP地址(因為在這時Request.UserHostAddress獲取到的就是這代理伺服器的IP)..
getIp()又有安全隱患
具體怎麼做就要看自己選擇了.


ServerVariables變數列表