说明:本文中的内容是我综合博客园上的博文和MSDN讨论区的资料,再通过本身的实际测试而得来,属于本身原创的内容说实话很少,写这一篇是为了记录本身在项目中做过的工作,同时也想抛砖引玉。参考的博文及其作者不才文均有提及。待到本身以后对HTTP、TCP/IP等常识学深入了,必然再来这里深入讨论这个内容。
一、名词首先说一下接下来要讲到的一些名词。
在Web开发中,我们大多都习惯使用HTTP请求头中的某些属性来获取客户真个IP地点,常见的属性是REMOTE_ADDR、HTTP_VIA和HTTP_X_FORWARDED_FOR。
这三个属性的含义,概略是如此:(摘自网上,欢迎斧正)
REMOTE_ADDR:该属性的值是客户端跟处事器“握手”时候的IP。如果使用了“匿名代办代理”,REMOTE_ADDR将显示代办代理处事器的IP。
X-Forwarded-For:是用来识别通过HTTP代办代理或负载均衡方法连接到Web处事器的客户端最原始的IP地点的HTTP请求头字段。
XFF的有效性依赖于代办代理处事器供给的连接原始IP地点的真实性,因此, XFF的有效使用应该保证代办代理处事器是可信的, 好比可以通过成立可信处事器白名单的方法。
这一HTTP头一般格局如下:
X-Forwarded-For: client1, proxy1, proxy2
此中的值通过逗号+空格,把多个IP地点区分隔, 最左边(client1)是最原始客户真个IP地点, 代办代理处事器每告成收到一个请求,就把请求来源IP地点添加到右边。 在上面这个例子中,这个请求告成通过了三台代办代理处事器:proxy1, proxy2 及 proxy3。请求由client1发出,达到了proxy3(proxy3可能是请求的终点)。请求刚从client1中发出时,XFF是空的,,请求被发往proxy1;通过proxy1的时候,client1被添加到XFF中,之后请求被发往proxy2;通过proxy2的时候,proxy1被添加到XFF中,之后请求被发往proxy3;通过proxy3时,proxy2被添加到XFF中,之后请求的的去向不明,如果proxy3不是请求终点,请求会被继续转发。
鉴于伪造这一字段非常容易,应该谨慎使用X-Forwarded-For字段。正常情况下XFF中最后一个IP地点是最后一个代办代理处事器的IP地点, 这凡是是一个对照可靠的信息来源。
(另附维基中对X-Forwarded-For的完整介绍:)
至于在使用这些属性的时候,属性的值是什么,网上查到一份这样的博文:获取用户IP地点的三个属性的区别(原作者不详)。
而在ASP.NET中,还可以通过此外一种方法获得客户真个IP地点,那就是通过Request东西中的UserHostAddress属性。在MSDN Library中,对这个属性是这样解释的:属性值是长途客户真个 IP 地点。
如果客户端使用了代办代理处事器,那么Request.UserHostAddress属性获得的就是代办代理处事器的IP地点。
二、要领好了,讲了那么多观点性的对象,咱们来讲一下实现的要领。
网上大大都要领的思路是:如果有代办代理IP,则优先获代替办代理IP,否则获取连接客户真个IP;或者调转过来,先获取连接客户真个IP,如获取掉败,则获代替办代理IP。
以下要领参考博文 asp.net获取客户端IP (作者comeonfyz)
-----------------------------------------------------------------------------------------------------------
/// <summary> /// 获取客户端IP地点 /// </summary> /// <returns>若掉败则返回回送地点</returns> public static string GetIP() { //如果客户端使用了代办代理处事器,则操作HTTP_X_FORWARDED_FOR找到客户端IP地点 string userHostAddress = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString().Split(‘,‘)[0].Trim(); //否则直接读取REMOTE_ADDR获取客户端IP地点 if (string.IsNullOrEmpty(userHostAddress)) { userHostAddress = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]; } //前两者均掉败,则操作Request.UserHostAddress属性获取IP地点,但此时无法确定该IP是客户端IP还是代办代理IP if (string.IsNullOrEmpty(userHostAddress)) { userHostAddress = HttpContext.Current.Request.UserHostAddress; } //最后判断获取是否告成,并查抄IP地点的格局(查抄其格局非常重要) if (!string.IsNullOrEmpty(userHostAddress) && IsIP(userHostAddress)) { return userHostAddress; } return "127.0.0.1"; } /// <summary> /// 查抄IP地点格局 /// </summary> /// <param></param> /// <returns></returns> public static bool IsIP(string ip) { return System.Text.RegularExpressions.Regex.IsMatch(ip, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$"); }
-----------------------------------------------------------------------------------------------------------