更新:19.10.19

客户端ip有可能有代理,有的是自己设置的,有的是浏览器强制插入的。比如微信内置浏览器默认有代理。

通过http头的方式可以获得最前端的ip,但是http头有可能被伪造,所以建议通过Request.UserHostAddress方式获得的ip。但是使用Request.UserHostAddress有一个问题,如果客户端有代理,就会获得最后一个代理的ip,客户端可以使用代理来隐藏自己的真实ip。具体使用那种方式参考具体的应用场景。

下例优先尝试使用http头的方式获得真实ip,如果获取失败再调用Request.UserHostAddress方法。

如果有多层代理,每一层代理都有可能把自己的ip加入http头,导致最后获得的ip不止一个,例如127.0.0.1,123.123.123.123,多个ip以逗号连接。应该确保函数返回的ip长度为单个ip的长度,否则在数据库应用中有可能导致长度溢出。

下例中Log.Error函数为自己写的日志输出函数,第一个参数为错误类型,第二个参数为错误信息。可以自行删除这个函数调用。

历史版本
19.10.19.2
18.5.12.1

代码:

/// <summary>

/// 获取客户端真实IP

/// </summary>

/// <returns></returns>

public static string getRealIP()

{

     try

     {

         string ip = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];

         if (string.IsNullOrEmpty(ip))

         {

             ip = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];

         }

         if (string.IsNullOrEmpty(ip))

         {

             ip = HttpContext.Current.Request.UserHostAddress;

         }

 

         if (string.IsNullOrEmpty(ip))

         {

             Log.Error("Function.getRealIP", "ip is null or empty.");

             return "0.0.0.0";

         }

 

         string[] ips = ip.Replace(" ", "").Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);

 

         string tip = ips[0];//多个ip只取第一个

 

         if (!ipValid(tip))//验证ip格式

         {

             Log.Error("Function.getRealIP", "invalidIp:" + tip);

             return "0.0.0.0";

         }

         return tip;

     }

     catch (Exception ex)

     {

         Log.Error("Function.getRealIP", ex.Message);

         return "0.0.0.0";

     }

}

 

/// <summary>

/// 验证ip格式

/// </summary>

/// <param name="ip">ip</param>

/// <returns></returns>

public static bool ipValid(string ip)

{

     try

     {

         return Regex.IsMatch(ip, @"^((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)$");

     }

     catch (Exception ex)

     {

         Log.Error("Function.ipValid", ex.Message);

         return false;

     }

}


发表评论

评论通过审核后才会显示
你的电子邮件地址不会被公开 * 为必填字段

Captcha Code

提交评论