C#獲取真實IP地址(IP轉(zhuǎn)為長整形、判斷是否內(nèi)網(wǎng)IP的方法)
今天查看登錄日志,發(fā)現(xiàn)http_x_forwarded_for獲取到的ip地址有些是內(nèi)網(wǎng)ip地址,有些則是公網(wǎng)和內(nèi)網(wǎng)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應(yīng)該是被其他軟件或者ISP修改過了,導(dǎo)致http_x_forwarded_for得不到真實的代理ip地址。之前登陸日志是要判斷ip地址是否在允許的ip段內(nèi)的,這樣導(dǎo)致無法登陸系統(tǒng)。最后修改代碼如下,增加判斷是否為內(nèi)網(wǎng)或者私有地址,是否符合ipv4的地址規(guī)格,不符合還是使用remote_addr來獲取客戶端的ip地址。
比較安全的獲取真實地址的實現(xiàn)代碼:
/// <summary>
/// C#將IP地址轉(zhuǎn)為長整形
/// </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地址是否為私有/內(nèi)網(wǎng)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地址有內(nèi)容,判斷是否符合ipv4地址或者是否為內(nèi)網(wǎng)地址
{
ip = ip.Trim().Replace(" ", "");
if (!Regex.IsMatch(ip, @"^\d+(\.\d+){3}$") || IsPrivateIp(ip))
ip = HttpContext.Current.Request.ServerVariables["remote_addr"];//不符合規(guī)則或者內(nèi)網(wǎng)/私有地址使用remote_addr代替
}
return ip;
}
2014-07-02更新:原來是 cdn加速的問題,cdn加速后,由于先判斷http_x_forwarded_for,http_x_forwarded_for是隨便可以偽造的,放置任何內(nèi)容的,所以下圖出現(xiàn)的ip地址中會有內(nèi)網(wǎng)地址或者出現(xiàn)2個ip地址的問題。所以獲取http_x_forwarded_for內(nèi)容時需要 split下獲取第一個項。
相關(guān)文章
C#創(chuàng)建Windows服務(wù)的圖文教程
本文主要介紹了C#創(chuàng)建Windows服務(wù)的圖文教程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06C#實現(xiàn)的圖片、string相互轉(zhuǎn)換類分享
這篇文章主要介紹了C#實現(xiàn)的圖片、string相互轉(zhuǎn)換類分享,本文直接給出類代碼,包含相互轉(zhuǎn)換的方法,需要的朋友可以參考下2015-03-03C#使用Twain協(xié)議開發(fā)一個高掃儀對接功能
這篇文章主要為大家詳細(xì)介紹了C#如何使用Twain協(xié)議開發(fā)一個高掃儀對接功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-02-02VS.net VSS時,編譯報錯:未能向文件“.csproj.FileListAbsolute.txt”寫入命令行 對路
在VSS上把項目的Bin和Obj目錄刪除,然后重新取出項目,編譯成功。2009-06-06C#開發(fā)微信門戶及應(yīng)用(2) 微信消息處理和應(yīng)答
文章主要為大家詳細(xì)介紹了C#開發(fā)微信門戶及應(yīng)用第二篇,微信消息處理和應(yīng)答,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-06-06Unity調(diào)用C++?dll實現(xiàn)打開雙目相機(jī)
這篇文章主要為大家詳細(xì)介紹了如何在Unity中調(diào)用C++?dll實現(xiàn)打開雙目相機(jī)的功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2022-05-05