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变量列表

猜你喜欢

转载自blog.csdn.net/u011261785/article/details/38439491