C#获取真实IP地址(IP转为长整形、判断是否内网IP的方法)
今天查看登录日志,发现http_x_forwarded_for获取到的ip地址有些是内网ip地址,有些则是公网和内网ip地址一起获取到,用逗号分隔开,日志截图如下:
之前获取ip地址的c#代码如下:
/// <summary>
/// c#获取客户端真实ip地址
/// </summary>
/// <returns></returns>
public static string getip()
{
string ip = httpcontext.current.request.servervariables["http_x_forwarded_for"];
if (usercheck.isnull(ip)) ip = httpcontext.current.request.servervariables["remote_addr"];
return ip;
}
看来http_x_forwarded_for应该是被其他软件或者isp修改过了,导致http_x_forwarded_for得不到真实的代理ip地址。之前登陆日志是要判断ip地址是否在允许的ip段内的,这样导致无法登陆系统。最后修改代码如下,增加判断是否为内网或者私有地址,是否符合ipv4的地址规格,不符合还是使用remote_addr来获取客户端的ip地址。
比较安全的获取真实地址的实现代码:
/// <summary>
/// c#将ip地址转为长整形
/// </summary>
/// <param name="ip"></param>
/// <returns></returns>
public static long iptonumber(string ip)
{
string[] arr = ip.split('.');
return 256 * 256 * 256 * long.parse(arr[0]) + 256 * 256 * long.parse(arr[1]) + 256 * long.parse(arr[2]) + long.parse(arr[3]);
}
/// <summary>
/// c#判断ip地址是否为私有/内网ip地址
/// </summary>
/// <param name="ip"></param>
/// <returns></returns>
public static bool isprivateip(string ip)
{
long abegin = iptonumber("10.0.0.0"), aend = iptonumber("10.255.255.255"),//a类私有ip地址
bbegin = iptonumber("172.16.0.0"), bend = iptonumber("172.31.255.255"),//'b类私有ip地址
cbegin = iptonumber("192.168.0.0"), cend = iptonumber("192.168.255.255"),//'c类私有ip地址
ipnum = iptonumber(ip);
return (abegin <= ipnum && ipnum <= aend) || (bbegin <= ipnum && ipnum <= bend) || (cbegin <= ipnum && ipnum <= cend);
}
/// <summary>
/// c#获取真实ip地址
/// </summary>
/// <returns></returns>
public static string getip()
{
string ip = httpcontext.current.request.servervariables["http_x_forwarded_for"];
if (usercheck.isnull(ip)) ip = httpcontext.current.request.servervariables["remote_addr"];
else//代理ip地址有内容,判断是否符合ipv4地址或者是否为内网地址
{
ip = ip.trim().replace(" ", "");
if (!regex.ismatch(ip, @"^\d+(\.\d+){3}$") || isprivateip(ip))
ip = httpcontext.current.request.servervariables["remote_addr"];//不符合规则或者内网/私有地址使用remote_addr代替
}
return ip;
}
2014-07-02更新:原来是 cdn加速的问题,cdn加速后,由于先判断http_x_forwarded_for,http_x_forwarded_for是随便可以伪造的,放置任何内容的,所以下图出现的ip地址中会有内网地址或者出现2个ip地址的问题。所以获取http_x_forwarded_for内容时需要 split下获取第一个项。
如对本文有疑问,
点击进行留言回复!!
相关文章:
-
-
-
C#实现猜数字游戏
本文实例为大家分享了c#实现猜数字游戏具体代码,供大家参考,具体内容如下给定一个0-100的随机数字猜其大小题目样式:电脑产生一个0到100之间的随机数字,并且...
[阅读全文]
-
-
C# 可空类型的具体使用
在项目中我们经常会遇到可为空类型,那么到底什么是可为空类型呢?下面我们将从4个方面为大家剖析。1、可空类型基础知识顾名思义,可空类型指的就是某个对象类型可以为空...
[阅读全文]
-
-
-
C#实现猜数字小游戏
本文实例为大家分享了c#实现猜数字小游戏的具体代码,供大家参考,具体内容如下效果如图:代码:using system;using system.collecti...
[阅读全文]
-
-
C#实现简单俄罗斯方块
最近在看《.net游戏编程入门经典 c#篇》 第一章介绍了如何制作俄罗斯方块,自己试了试按照书上的步骤,可算是完成了。于是写下这篇文章留作纪念。1.类的设计在充...
[阅读全文]
-
网友评论