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()又有安全隱患
具體怎麼做就要看自己選擇了.