获取ip
How to get a user's client IP address in ASP.NET?
Often you will want to know the IP address of someone visiting your website. While ASP.NET has several ways to do this one of the best ways we've seen is by using the "HTTP_X_FORWARDED_FOR" of the ServerVariables collection.
Here's why...
Sometimes your visitors are behind either a proxy server or a router and the standard Request.UserHostAddress
only captures the IP address of the proxy server or router. When this is the case the user's IP address is then stored in the server variable ("HTTP_X_FORWARDED_FOR").
So what we want to do is first check "HTTP_X_FORWARDED_FOR" and if that is empty we then simply return ServerVariables("REMOTE_ADDR")
.
While this method is not foolproof, it can lead to better results. Below is the ASP.NET code in VB.NET, taken from James Crowley's blog post "Gotcha: HTTP_X_FORWARDED_FOR returns multiple IP addresses"
protected string GetIPAddress()
{
System.Web.HttpContext context = System.Web.HttpContext.Current;
string ipAddress = context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; if (!string.IsNullOrEmpty(ipAddress))
{
string[] addresses = ipAddress.Split(',');
if (addresses.Length != )
{
return addresses[];
}
} return context.Request.ServerVariables["REMOTE_ADDR"];
}
版本二 考虑了代理
private string GetUserIP(NameValueCollection serverVariables)
{
string userIp;
if (serverVariables["HTTP_VIA"] != null)
{
var ip = serverVariables["HTTP_X_FORWARDED_FOR"];
if (ip != null)
{
userIp = ip.Split(',')[];
}
else
{
userIp = serverVariables["REMOTE_ADDR"];
}
}
else
{
userIp = serverVariables["REMOTE_ADDR"];
}
return userIp;
}
版本三 考虑HTTP_X_REAL_IP
private string GetIpFromServerVariables(NameValueCollection serverVariables)
{
if (serverVariables == null)
{
return null;
} var ip = serverVariables["HTTP_X_FORWARDED_FOR"];
ip = ip?.Split(',')[];
if (string.IsNullOrWhiteSpace(ip))
{
ip = serverVariables["HTTP_X_REAL_IP"];
}
if (string.IsNullOrWhiteSpace(ip))
{
ip = serverVariables["REMOTE_ADDR"];
}
return ip;
}
What is the difference between Request.UserHostAddress and Request.ServerVariables[“REMOTE_ADDR”].ToString()
Short answer: The two are identical.
Long answer: To determine the difference between the two use Reflector (or whatever disassembler you prefer).
The code for the HttpRequest.UserHostAddress
property follows:
public string UserHostAddress
{
get
{
if (this._wr != null)
{
return this._wr.GetRemoteAddress();
}
return null;
}
}
Note that it returns _wr.GetRemoteAddress()
. The _wr
variable is an instance of an HttpWorkerRequest
object. There are different classes derived from HttpWorkerRequest
and which one is used depends on whether you are using IIS 6, IIS 7 or beyond, and some other factors, but all of the ones you would be using in a web application have the same code for GetRemoteAddress()
, namely:
public override string GetRemoteAddress()
{
return this.GetServerVariable("REMOTE_ADDR");
}
As you can see, GetRemoteAddress()
simply returns the server variable REMOTE_ADDR
.
As far as which one to use, I'd suggest the UserHostAddress
property since is doesn't rely on "magic strings."
Happy Programming
【干货分享】获取用户IP的正确姿势
如何获取用户的IP,这个需求简直是太常见了,像登录入口,注册入口,投票,日志记录,api接口中判断同一个ip单位时间内的请求数,可是怎么去获取用户的真实IP呢?
网上的代码很多,好多人直接拿来就用,却没有想到带来了很大的安全问题。
1.代码示例
这是网上的一个示范例子,我们很多同事也这么写,上面这个例子是php实现的,由于HTTP_CLIENT_IP,HTTP_X_FORWARDED_FOR,HTTP_X_FORWARDED,HTTP_X_CLUSTER_CLIENT_IP,HTTP_FORWARDED_FOR,HTTP_FORWARDED,HTTP_VIA (经过的 Proxy)这些以HTTP打头的server变量都是用户可控的,由此可导致xss,认证绕过等缺陷。
下面我们看下python的例子:
也是由于客户端变量可控导致获取的ip可为任意值。在此例中,X-Real-IP是nginx特有的,通过配置proxy_set_header X-Real-IP $remote_addr;从REMOTE_ADDR中取值。
2 X-Forwarded-For和 REMOTE_ADDR的区别
REMOTE_ADDR代表着客户端的IP,但是这个客户端是相对服务器而言的,也就是实际上与服务器相连的机器的IP(建立tcp连接的那个),这个值是不可伪造的,如果没有代理的话,这个值就是用户实际的IP值,有代理的话,用户的请求会经过代理再到服务器,这个时候REMOTE_ADDR会被设置为代理机器的IP值。
正如前面所说,有了代理就获取不了用户的真实IP,由此X-Forwarded-For应运而生,它是一个非正式协议,在请求转发到代理的时候代理会添加一个X-Forwarded-For头,将连接它的客户端IP(也就是你的上网机器IP)加到这个头信息里,这样末端的服务器就能获取真正上网的人的IP了。
假设用户的请求顺序如下:
网民电脑ip->代理服务器1–>代理服务器2–>目标服务器
REMOTE_ADDR:代理服务器2的IP值
X-Forwarded-For就是:网民电脑IP,代理1的IP,代理2的IP
在这里只有REMOTE_ADDR是可信的,其他从客户端获取的数据都是不可信的,都是可伪造的。下面简单示例下一个篡改X-Forwarded-For的情况:
3 正确的代码示例
在X-Forwarded-For信息头中可以提取真实的用户IP,但是这个IP是可以伪造的,如果从X-Forwarded-For提取IP作为用户的IP对于存在登录次数,api速率限制等一些接口是致命的缺陷,因为任意构造出无数的合法或者非法IP地址。
而REMOTE_ADDR只是服务器前端的IP地址,如果没有代理就是用户的真实地址。这个是不可伪造的,而且代理是有限的,可以基于此来获取IP。在wordpress中,获取客户的IP地址代码如下:
4 总结
X-Forwarded-For可被用户伪造,不应该被信任;REMOTE_ADDR是使用“REMOTE_ADDR”机器的前一个建立tcp连接的机器的地址,是不可伪造的,在无代理时可以理解为用户的IP地址,有反向代理时,先将REMOTE_ADDR赋给X-Real-IP,最后可以从X-Real-IP中获取用户的IP。
参考文献:
http://gong1208.iteye.com/blog/1559835
http://devco.re/blog/2014/06/19/client-ip-detection/
http://blog.pengqi.me/2013/04/20/remote-addr-and-x-forwarded-for/
ASP.NET获取用户端的真实IP
改进版获取用户真实IP
/// <summary>
/// 取得客户端真实IP。如果有代理则取第一个非内网地址
/// Author:codeo.cn
/// </summary>
/// <returns></returns>
public static string GetIPAddress()
{
string strresult = string.Empty;
strresult = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (strresult != null && strresult != string.Empty)
{
//可能有代理
if (strresult.IndexOf(".") == -) //没有“.”肯定是非IPv4格式
{
strresult = null;
}
else
{
if (strresult.IndexOf(".") != -)
{
//有“,”,估计多个代理。取第一个不是内网的IP。
strresult = strresult.Replace(" ", "").Replace("'", "");
string[] strarrtemparyip = strresult.Split(",;".ToCharArray()); for (int i = ; i < strarrtemparyip.Length; i++)
{
if (IsIPAddress(strarrtemparyip[i]) && strarrtemparyip[i].Substring(, ) != "10." && strarrtemparyip[i].Substring(, ) != "192.168" && strarrtemparyip[i].Substring(, ) != "172.16.")
{
return strarrtemparyip[i]; //找到不是内网的地址
}
}
}
else if (IsIPAddress(strresult)) //代理即是IP格式
{
return strresult;
}
else
{
strresult = null; //代理中的内容 非IP,取IP
}
}
}
string strIpAddress = (HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null && HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != string.Empty ? HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] : HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]); if (null == strresult || strresult == string.Empty)
{
strresult = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
}
if (strresult == null || strresult == string.Empty)
{
strresult = HttpContext.Current.Request.UserHostAddress;
} return strresult;
}
/// <summary>
/// 判断是否是IP地址格式 0.0.0.0
/// Author:codeo.cn
/// </summary>
/// <param name="strIp">待判断的IP地址</param>
/// <returns>true or false</returns>
private static bool IsIPAddress(string strIp)
{
if (strIp == null || strIp == string.Empty || strIp.Length < || strIp.Length > )
{
return false;
} string strRegformat = @"^d{1,3}[.]d{1,3}[.]d{1,3}[.]d{1,3}___FCKpd___0quot"; Regex regex = new Regex(strRegformat, RegexOptions.IgnoreCase); return regex.IsMatch(strIp);
}
获取ip的更多相关文章
- windows下获取IP地址的两种方法
windows下获取IP地址的两种方法: 一种可以获取IPv4和IPv6,但是需要WSAStartup: 一种只能取到IPv4,但是不需要WSAStartup: 如下: 方法一:(可以获取IPv4和I ...
- 【PHP开发篇】一个统计客户端商机提交的获取IP地址
1.对客服提交数据的ip地址记录. 获取ip地址的方法: public function getIP() { global $ip; if (getenv("HTTP_X_REAL_IP&q ...
- VMware桥接模式无法自动化获取IP的解决方法
虚拟机桥接无法自动获取IP的解决方法 在虚拟机VM里面装了centos系统,网卡选用桥接方式. 刚开始的时候还能自动获取到IP地址,突然有一天IP消失了,再怎么重启都无法获取IP地址.因为之前是可以获 ...
- PXE DHCP获取IP与传统DHCP获取IP地址的区别
正常的DHCP获取IP的流程(Discover-Offer-Request-Ack): (Discovery)主机端在LAN中发布MAC地址为FF:FF:FF:FF:FF:FF的广播来寻找DHCP服务 ...
- 获取ip ,百度地图坐标点 和 在 后台调用 url()
protected void getip() { string ips = HttpContext.Current.Request.UserHostA ...
- 在 shell 脚本获取 ip、数字转换等网络操作
在 shell 脚本获取 ip.数字转换等网络操作 ip 和数字的相互转换 ip转换为数字 :: function ip2num() { local ip=$1 local a=$(echo $ip ...
- 获取 IP 地址
package j2se.core.net.base; import java.net.InetAddress;import java.net.UnknownHostException; public ...
- PHP获取IP地址
获取客户端IP地址:: function getIp(){ if(!empty($_SERVER['HTTP_CLIENT_IP'])){ return $_SERVER['HTTP_CLIENT_I ...
- linux系统下获取IP,MAC,子网掩码,网关
获取IP和子网掩码 int getLocalInfo(char IP[],char Mask[]) { int fd; int interfaceNum = 0; struct ifreq buf[1 ...
- C#获取IP和主机名
System.Net.IPAddress addr; //获取IP addr = new System.Net.IPAddress ( Dns.GetHostByName ( Dns.GetHostN ...
随机推荐
- C# 常用类
一.Convert 主要用于数据类型的转换,常用的静态方法有: Convert.ToSingle():把数据转换为单精度浮点数,参数常为字符串 Convert.ToDouble():转为双精度浮点数 ...
- Ceph与OpenStack的Glance相结合
http://docs.ceph.com/docs/master/rbd/rbd-openstack/?highlight=nova#kilo 在Ceoh的admin-node上进行如下操作: 1. ...
- GDC2016 【全境封锁】的全局照明技术
现在全力支持公司的GAD平台了,很多的内部分享也可以放出来 http://gad.qq.com/article/detail/7159232
- js串讲回顾
注:1.xx.nextSibling.css.xxx->xx的下一个元素的css样式;2. window.opener.document.getElementById("cms&quo ...
- 【C51】74HC573芯片
74HC573是一个8位3态带锁存高速的逻辑芯片.下面介绍使用. 参数(仅供参考) Vcc 2~6V I in +-20mA I out +- 35mA 引脚图和引脚作用 ...
- thinkphp的钩子的两种配置和两种调用方法
thinkphp的钩子行为类是一个比较难以理解的问题,网上有很多写thinkphp钩子类的文章,我也是根据网上的文章来设置thinkphp的钩子行为的,但根据这些网上的文章,我在设置的过程中,尝试了十 ...
- Inside Flask - json 处理
Inside Flask - json 处理 在处理 web api 时,json 是非常好用的数据交换格式,它结构简单,基本上各种主流的编程语言都有良好的支持工具. flask 中处理 json 时 ...
- 大商创开通用户和店铺 sql追踪
添加用户(账号:wmy123 ,密码:wzd222,id:69)INSERT INTO `dsc1`.`dsc_users` (user_name,mobile_phone,email,passwor ...
- CoreAnimation--CALayer的动画
CoreAnimation--CALayer的动画 核心动画中所有类都遵守CAMediaTiming CAAnaimation和CAPropertyAnimation都是抽象类,本身不具备动画效果,必 ...
- LUA语言注意点归集
统计元素个数接口--只计算以整数为下标的 第一段连续元素的数目 #tab 和 table.getn() http://ju.outofmemory.cn/entry/29450 我们修改table: ...