我们有请求。UserHostAddress在ASP. ASP. ASP中获取IP地址。NET,但这通常是用户的ISP的IP地址,而不是用户点击链接的机器IP地址。如何获取真实IP地址?

例如,在Stack Overflow用户配置文件中,它是:“上次帐户活动:4小时前从86.123.127.8开始”,但我的机器IP地址有点不同。Stack Overflow如何获得这个地址?

在一些web系统中,出于某些目的有一个IP地址检查。例如,对于某个IP地址,每24小时用户只能点击5次下载链接吗?这个IP地址应该是唯一的,而不是针对一个拥有大量客户端或互联网用户的ISP。

我听懂了吗?


您还认为用户IP地址是什么?如果你想要网络适配器的IP地址,恐怕在Web应用程序中没有办法做到这一点。如果你的用户在NAT或其他东西后面,你也无法获得IP。

更新:虽然有些网站使用IP来限制用户(如rapidshare),但它们在NAT环境中不能正常工作。


IP地址是“七层堆栈”中的网络层的一部分。网络层可以对IP地址做任何它想做的事情。这就是代理服务器、NAT、中继或其他设备所发生的情况。

应用层不应该以任何方式依赖于IP地址。特别是,IP地址不意味着是网络连接一端的标识符以外的任何标识符。一旦连接被关闭,(同一用户的)IP地址就会发生变化。


就像别人说的,你不可能做到你所要求的。如果你描述一下你想要解决的问题也许有人可以帮你?

如。

您是否试图唯一地标识您的用户? 您是否可以使用cookie或会话ID来代替IP地址?

Edit The address you see on the server shouldn't be the ISP's address, as you say that would be a huge range. The address for a home user on broadband will be the address at their router, so every device inside the house will appear on the outside to be the same, but the router uses NAT to ensure that traffic is routed to each device correctly. For users accessing from an office environment the address may well be the same for all users. Sites that use IP address for ID run the risk of getting it very wrong - the examples you give are good ones and they often fail. For example my office is in the UK, the breakout point (where I "appear" to be on the internet) is in another country where our main IT facility is, so from my office my IP address appears to be not in the UK. For this reason I can't access UK only web content, such as the BBC iPlayer). At any given time there would be hundreds, or even thousands, of people at my company who appear to be accessing the web from the same IP address.

当你在写服务器代码时,你永远不能确定你看到的IP地址指的是什么。一些用户喜欢这种方式。有些人故意使用代理或VPN来进一步混淆你。

当你说你的机器地址与StackOverflow上显示的IP地址不同时,你是如何找到你的机器地址的?如果您只是使用ipconfig或类似的工具在本地查找,我希望由于我上面概述的原因它会有所不同。如果你想再次确认外界的看法,可以看看whatismyipaddress.com/。

这个关于NAT的维基百科链接将为您提供一些背景知识。


通常你会想知道访问你网站的人的IP地址。而ASP。NET有几种方法可以做到这一点,我们所见过的最好的方法之一是使用ServerVariables集合的“HTTP_X_FORWARDED_FOR”。

这是为什么…

有时,您的访问者位于代理服务器或路由器和标准请求的后面。UserHostAddress仅捕获代理服务器或路由器的IP地址。在这种情况下,用户的IP地址存储在服务器变量(“HTTP_X_FORWARDED_FOR”)中。

所以我们要做的是首先检查“HTTP_X_FORWARDED_FOR”,如果这是空的,我们然后简单地返回ServerVariables(“REMOTE_ADDR”)。

虽然这种方法不是万无一失的,但它可以带来更好的结果。下面是ASP。NET代码在VB。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"];
}

VB。网

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

你能做的是存储你的用户的路由器IP和转发的IP,并尝试使用IP[外部公共和内部私有]使其可靠。但几天后,客户端可能会从路由器分配新的内部IP,但它会更可靠。


你可以使用:

System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()).AddressList.GetValue(0).ToString();

更新: 感谢布鲁诺·洛佩斯。如果可以访问多个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"];
    }

使用这个

Dns.GetHostEntry(Dns.GetHostName())

我想我应该和大家分享我的经验。好吧,我看到在某些情况下REMOTE_ADDR将不会得到你正在寻找的东西。例如,如果你在后台有一个负载均衡器,如果你试图获取客户端的IP,那么你就会遇到麻烦。我用我的IP屏蔽软件检查过了,我还和我在不同大洲的同事们检查过了。这就是我的解。

当我想知道一个客户端的IP时,我试图选择每一个可能的证据,这样我就可以确定它们是否唯一:

在这里,我发现了另一个server -var,如果你想获得客户端的确切IP,它可以帮助你。所以我使用:HTTP_X_CLUSTER_CLIENT_IP

HTTP_X_CLUSTER_CLIENT_IP总是得到客户端的确切IP。在任何情况下,如果它不给你的值,你应该然后寻找HTTP_X_FORWARDED_FOR,因为它是第二个最好的候选人,让你的客户端IP,然后REMOTE_ADDR变量,可能或可能不返回你的IP,但对我来说,拥有这三个是我发现最好的东西来监控他们。

我希望这能帮助到一些人。


如果是c#这样看,是很简单的

string clientIp = (Request.ServerVariables["HTTP_X_FORWARDED_FOR"] ?? 
                   Request.ServerVariables["REMOTE_ADDR"]).Split(',')[0].Trim();

Try:

using System.Net;

public static string GetIpAddress()  // Get IP Address
{
    string ip = "";     
    IPHostEntry ipEntry = Dns.GetHostEntry(GetCompCode());
    IPAddress[] addr = ipEntry.AddressList;
    ip = addr[2].ToString();
    return ip;
}
public static string GetCompCode()  // Get Computer Name
{   
    string strHostName = "";
    strHostName = Dns.GetHostName();
    return strHostName;
}

在ashx文件中使用

public string getIP(HttpContext c)
{
    string ips = c.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
    if (!string.IsNullOrEmpty(ips))
    {
        return ips.Split(',')[0];
    }
    return c.Request.ServerVariables["REMOTE_ADDR"];
}

string IP = HttpContext.Current.Request.Params["HTTP_CLIENT_IP"] ?? HttpContext.Current.Request.UserHostAddress;

如果您正在使用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;
    }
}

then

string IPAddress = Request.GetIPAddress();

到目前为止,所有的响应都考虑了非标准化但非常常见的X-Forwarded-For报头。有一个标准化的转发头,它有点难以解析。一些例子如下:

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

我已经编写了一个类,在确定客户端的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;
        }
    }
}

下面是我用来验证我的解决方案的一些单元测试:

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; }
        }
    }
}

结合@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;
    }
}

大家好,你会发现大多数代码将返回你的服务器ip地址而不是客户端ip地址。然而,这段代码返回正确的客户端ip地址。试一试。 更多信息,请检查这个

https://www.youtube.com/watch?v=Nkf37DsxYjI

对于使用javascript获取本地IP地址,您可以使用 将这段代码放在脚本标记中

<script>
    var RTCPeerConnection = /*window.RTCPeerConnection ||*/
     window.webkitRTCPeerConnection || window.mozRTCPeerConnection;

         if (RTCPeerConnection) (function () {
             var rtc = new RTCPeerConnection({ iceServers: [] });
             if (1 || window.mozRTCPeerConnection) {      
                 rtc.createDataChannel('', { reliable: false });
             };

             rtc.onicecandidate = function (evt) {

                 if (evt.candidate)
                     grepSDP("a=" + evt.candidate.candidate);
             };
             rtc.createOffer(function (offerDesc) {
                 grepSDP(offerDesc.sdp);
                 rtc.setLocalDescription(offerDesc);
             }, function (e) { console.warn("offer failed", e); });


             var addrs = Object.create(null);
             addrs["0.0.0.0"] = false;
             function updateDisplay(newAddr) {
                 if (newAddr in addrs) return;
                 else addrs[newAddr] = true;
                 var displayAddrs = Object.keys(addrs).filter(function
(k) { return addrs[k]; });
                 document.getElementById('list').textContent =
displayAddrs.join(" or perhaps ") || "n/a";
             }

             function grepSDP(sdp) {
                 var hosts = [];
                 sdp.split('\r\n').forEach(function (line) { 
                     if (~line.indexOf("a=candidate")) {   
                         var parts = line.split(' '),   
                             addr = parts[4],
                             type = parts[7];
                         if (type === 'host') updateDisplay(addr);
                     } else if (~line.indexOf("c=")) {      
                         var parts = line.split(' '),
                             addr = parts[2];
                         updateDisplay(addr);
                     }
                 });
             }
         })(); else
         {
             document.getElementById('list').innerHTML = "<code>ifconfig| grep inet | grep -v inet6 | cut -d\" \" -f2 | tail -n1</code>";
             document.getElementById('list').nextSibling.textContent = "In Chrome and Firefox your IP should display automatically, by the power of WebRTCskull.";

         }




</script>
<body>
<div id="list"></div>
</body>

和获取您的公共ip地址,您可以使用 将这段代码放在脚本标记中

  function getIP(json) {
    document.write("My public IP address is: ", json.ip);
  }


<script type="application/javascript" src="https://api.ipify.org?format=jsonp&callback=getIP"></script>

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();
                }
            }
        }
    }
}

Use;

string _ip = this.GetClientIP();

它的简单。试一试:

var remoteIpAddress = Request.HttpContext.Connection.RemoteIpAddress;

就这样吧!)


在NuGet包中安装Microsoft.AspNetCore.HttpOverrides 然后尝试:

public class ClientDeviceInfo
    {
        private readonly IHttpContextAccessor httpAccessor;

        public ClientDeviceInfo(IHttpContextAccessor httpAccessor)
        {
            this.httpAccessor = httpAccessor;
        }

        public string GetClientLocalIpAddress()
        {
            return httpAccessor.HttpContext.Connection.LocalIpAddress.ToString();
        }

        public string GetClientRemoteIpAddress()
        {
            return httpAccessor.HttpContext.Connection.RemoteIpAddress.ToString();
        }

        public string GetClientLocalPort()
        {
            return httpAccessor.HttpContext.Connection.LocalPort.ToString();
        }

        public string GetClientRemotePort()
        {
            return httpAccessor.HttpContext.Connection.RemotePort.ToString();
        }
     }

简单的

var ip =  Request.UserHostAddress;

这就是……