Meh*_*hdi 373 c# asp.net client ip-address
我们必须Request.UserHostAddress在ASP.NET中获取IP地址,但这通常是用户的ISP的IP地址,而不是用户的机器IP地址,例如单击链接.我怎样才能获得真实的IP地址?
例如,在Stack Overflow用户配置文件中,它是:"上次帐户活动:4小时前从86.123.127.8",但我的机器IP地址有点不同.Stack Overflow如何获得此地址?
在某些Web系统中,存在用于某些目的的IP地址检查.例如,使用某个IP地址,用户每24小时只能点击5次下载链接?此IP地址应该是唯一的,不适用于拥有大量客户端或Internet用户的ISP.
我理解得好吗?
man*_*kun 432
通常,您会想知道访问您网站的人的IP地址.虽然ASP.NET有几种方法可以做到这一点,但我们看到的最佳方法之一是使用ServerVariables集合的"HTTP_X_FORWARDED_FOR".
这就是为什么......
有时您的访问者位于代理服务器或路由器后面,标准Request.UserHostAddress仅捕获代理服务器或路由器的IP地址.在这种情况下,用户的IP地址随后存储在服务器变量("HTTP_X_FORWARDED_FOR")中.
所以我们要做的是首先检查"HTTP_X_FORWARDED_FOR",如果是空的,我们就会返回ServerVariables("REMOTE_ADDR").
虽然这种方法并非万无一失,但它可以带来更好的结果.下面是VB.NET中的ASP.NET代码,取自James Crowley的博客文章"Gotcha:HTTP_X_FORWARDED_FOR返回多个IP地址"
C#
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 != 0)
{
return addresses[0];
}
}
return context.Request.ServerVariables["REMOTE_ADDR"];
}
Run Code Online (Sandbox Code Playgroud)
VB.NET
Public Shared Function GetIPAddress() As String
Dim context As System.Web.HttpContext = System.Web.HttpContext.Current
Dim sIPAddress As String = context.Request.ServerVariables("HTTP_X_FORWARDED_FOR")
If String.IsNullOrEmpty(sIPAddress) Then
Return context.Request.ServerVariables("REMOTE_ADDR")
Else
Dim ipArray As String() = sIPAddress.Split(New [Char]() {","c})
Return ipArray(0)
End If
End Function
Run Code Online (Sandbox Code Playgroud)
Ste*_*eve 137
正如其他人所说,你不能做你所要求的.如果你描述了你试图解决的问题,也许有人可以提供帮助?例如,您是否尝试唯一标识您的用户?您是否可以使用cookie或会话ID而不是IP地址?
编辑您在服务器上看到的地址不应该是ISP的地址,正如您所说,这将是一个巨大的范围.宽带上的家庭用户的地址将是其路由器上的地址,因此房屋内的每个设备将在外部显示为相同,但路由器使用NAT来确保流量正确地路由到每个设备.对于从办公室环境访问的用户,所有用户的地址可能相同.使用IP地址进行身份验证的网站存在使其非常错误的风险 - 您提供的示例很好,但它们经常会失败.例如我的办公室在英国,突破点(我"出现"在互联网上)位于我们主要IT设施所在的另一个国家,所以从我的办公室来看,我的IP地址似乎不在英国.出于这个原因,我无法访问仅限英国的网络内容,例如BBC iPlayer.在任何时候,我公司的数百人甚至数千人似乎都是从同一个IP地址访问网络.
在编写服务器代码时,您永远无法确定您看到的IP地址是指的是什么.有些用户喜欢这种方式.有些人故意使用代理或VPN来进一步混淆你.
当您说您的机器地址与StackOverflow上显示的IP地址不同时,您如何找到您的机器地址?如果您只是在本地使用ipconfig或类似的东西,我会期望它与我上面概述的原因不同.如果你想仔细检查外界认为有什么看看whatismyipaddress.com/.
alg*_*eat 72
更新: 感谢Bruno Lopes.如果可能有多个ip地址,则需要使用此方法:
private string GetUserIP()
{
string ipList = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (!string.IsNullOrEmpty(ipList))
{
return ipList.Split(',')[0];
}
return Request.ServerVariables["REMOTE_ADDR"];
}
Run Code Online (Sandbox Code Playgroud)
Meh*_*ari 23
你还认为用户的IP地址是什么?如果你想要网络适配器的IP地址,我担心在Web应用程序中没有可能的方法.如果您的用户在NAT或其他东西后面,您也无法获得IP.
更新:虽然有些网站使用IP来限制用户(如rapidshare),但它们在NAT环境中无法正常工作.
Jua*_*ona 23
如果是c#看到这种方式,很简单
string clientIp = (Request.ServerVariables["HTTP_X_FORWARDED_FOR"] ??
Request.ServerVariables["REMOTE_ADDR"]).Split(',')[0].Trim();
Run Code Online (Sandbox Code Playgroud)
KMX*_*KMX 22
我想我应该与大家分享我的经验.我在某些情况下看到REMOTE_ADDR无法满足您的需求.例如,如果您在场景后面有一个负载均衡器,并且如果您尝试获取客户端的IP,那么您将遇到麻烦.我用我的IP掩蔽软件检查了它,我还检查了同事在不同的大陆.所以这是我的解决方案.
当我想知道客户的IP时,我会尝试选择所有可能的证据,以便我可以确定它们是否是唯一的:
在这里,我发现了另一个sever-var,如果你想获得客户端的确切IP,它可以帮助你们.所以我正在使用:HTTP_X_CLUSTER_CLIENT_IP
HTTP_X_CLUSTER_CLIENT_IP始终为您提供客户端的确切IP.在任何情况下,如果它没有给你价值,你应该寻找HTTP_X_FORWARDED_FOR,因为它是第二个获得客户端IP的最佳候选者,然后是REMOTE_ADDR var,它可能会也可能不会返回你的IP但是我拥有所有这些三是我发现监控它们的最佳方法.
我希望这可以帮助一些人.
Bat*_*mer 16
您可以使用:
System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()).AddressList.GetValue(0).ToString();
Run Code Online (Sandbox Code Playgroud)
Joh*_*ers 13
IP地址是"七层堆栈"中网络层的一部分.网络层可以对IP地址执行任何操作.这就是代理服务器,NAT,中继等等.
Application层不应以任何方式依赖于IP地址.特别地,IP地址并不意味着除了网络连接的一端的标识符之外的任何标识符.一旦连接关闭,您应该期望(同一用户的)IP地址发生变化.
如果您使用的是CloudFlare,则可以尝试以下扩展方法:
public static class IPhelper
{
public static string GetIPAddress(this HttpRequest Request)
{
if (Request.Headers["CF-CONNECTING-IP"] != null) return Request.Headers["CF-CONNECTING-IP"].ToString();
if (Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null) return Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString();
return Request.UserHostAddress;
}
}
Run Code Online (Sandbox Code Playgroud)
然后
string IPAddress = Request.GetIPAddress();
Run Code Online (Sandbox Code Playgroud)
string IP = HttpContext.Current.Request.Params["HTTP_CLIENT_IP"] ?? HttpContext.Current.Request.UserHostAddress;
Run Code Online (Sandbox Code Playgroud)
到目前为止,所有响应都考虑了非标准化但非常常见的X-Forwarded-For标题.有一个标准化的Forwarded标题,解析起来有点困难.一些例子如下:
Forwarded: for="_gazonk"
Forwarded: For="[2001:db8:cafe::17]:4711"
Forwarded: for=192.0.2.60;proto=http;by=203.0.113.43
Forwarded: for=192.0.2.43, for=198.51.100.17
Run Code Online (Sandbox Code Playgroud)
我编写了一个类,在确定客户端的IP地址时会考虑这两个标头.
using System;
using System.Web;
namespace Util
{
public static class IP
{
public static string GetIPAddress()
{
return GetIPAddress(new HttpRequestWrapper(HttpContext.Current.Request));
}
internal static string GetIPAddress(HttpRequestBase request)
{
// handle standardized 'Forwarded' header
string forwarded = request.Headers["Forwarded"];
if (!String.IsNullOrEmpty(forwarded))
{
foreach (string segment in forwarded.Split(',')[0].Split(';'))
{
string[] pair = segment.Trim().Split('=');
if (pair.Length == 2 && pair[0].Equals("for", StringComparison.OrdinalIgnoreCase))
{
string ip = pair[1].Trim('"');
// IPv6 addresses are always enclosed in square brackets
int left = ip.IndexOf('['), right = ip.IndexOf(']');
if (left == 0 && right > 0)
{
return ip.Substring(1, right - 1);
}
// strip port of IPv4 addresses
int colon = ip.IndexOf(':');
if (colon != -1)
{
return ip.Substring(0, colon);
}
// this will return IPv4, "unknown", and obfuscated addresses
return ip;
}
}
}
// handle non-standardized 'X-Forwarded-For' header
string xForwardedFor = request.Headers["X-Forwarded-For"];
if (!String.IsNullOrEmpty(xForwardedFor))
{
return xForwardedFor.Split(',')[0];
}
return request.UserHostAddress;
}
}
}
Run Code Online (Sandbox Code Playgroud)
以下是我用来验证解决方案的一些单元测试:
using System.Collections.Specialized;
using System.Web;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace UtilTests
{
[TestClass]
public class IPTests
{
[TestMethod]
public void TestForwardedObfuscated()
{
var request = new HttpRequestMock("for=\"_gazonk\"");
Assert.AreEqual("_gazonk", Util.IP.GetIPAddress(request));
}
[TestMethod]
public void TestForwardedIPv6()
{
var request = new HttpRequestMock("For=\"[2001:db8:cafe::17]:4711\"");
Assert.AreEqual("2001:db8:cafe::17", Util.IP.GetIPAddress(request));
}
[TestMethod]
public void TestForwardedIPv4()
{
var request = new HttpRequestMock("for=192.0.2.60;proto=http;by=203.0.113.43");
Assert.AreEqual("192.0.2.60", Util.IP.GetIPAddress(request));
}
[TestMethod]
public void TestForwardedIPv4WithPort()
{
var request = new HttpRequestMock("for=192.0.2.60:443;proto=http;by=203.0.113.43");
Assert.AreEqual("192.0.2.60", Util.IP.GetIPAddress(request));
}
[TestMethod]
public void TestForwardedMultiple()
{
var request = new HttpRequestMock("for=192.0.2.43, for=198.51.100.17");
Assert.AreEqual("192.0.2.43", Util.IP.GetIPAddress(request));
}
}
public class HttpRequestMock : HttpRequestBase
{
private NameValueCollection headers = new NameValueCollection();
public HttpRequestMock(string forwarded)
{
headers["Forwarded"] = forwarded;
}
public override NameValueCollection Headers
{
get { return this.headers; }
}
}
}
Run Code Online (Sandbox Code Playgroud)
结合@Tony和@mangokun的答案,我创建了以下扩展方法:
public static class RequestExtensions
{
public static string GetIPAddress(this HttpRequest Request)
{
if (Request.Headers["CF-CONNECTING-IP"] != null) return Request.Headers["CF-CONNECTING-IP"].ToString();
if (Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null)
{
string ipAddress = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (!string.IsNullOrEmpty(ipAddress))
{
string[] addresses = ipAddress.Split(',');
if (addresses.Length != 0)
{
return addresses[0];
}
}
}
return Request.UserHostAddress;
}
}
Run Code Online (Sandbox Code Playgroud)
public static class Utility
{
public static string GetClientIP(this System.Web.UI.Page page)
{
string _ipList = page.Request.Headers["CF-CONNECTING-IP"].ToString();
if (!string.IsNullOrWhiteSpace(_ipList))
{
return _ipList.Split(',')[0].Trim();
}
else
{
_ipList = page.Request.ServerVariables["HTTP_X_CLUSTER_CLIENT_IP"];
if (!string.IsNullOrWhiteSpace(_ipList))
{
return _ipList.Split(',')[0].Trim();
}
else
{
_ipList = page.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (!string.IsNullOrWhiteSpace(_ipList))
{
return _ipList.Split(',')[0].Trim();
}
else
{
return page.Request.ServerVariables["REMOTE_ADDR"].ToString().Trim();
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
使用;
string _ip = this.GetClientIP();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
555433 次 |
| 最近记录: |