因为要在项目中取到客户端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()又有安全隐患
具体怎么做就要看自己选择了.