C# 如何在 ASP.NET 中获取用户的客户端 IP 地址?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/735350/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 23:09:39  来源:igfitidea点击:

How to get a user's client IP address in ASP.NET?

c#asp.netclientip-address

提问by Mehdi

We have Request.UserHostAddressto get the IP address in ASP.NET, but this is usually the user's ISP's IP address, not exactly the user's machine IP address who for example clicked a link. How can I get the real IP Address?

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

For example, in a Stack Overflow user profile it is: "Last account activity: 4 hours ago from 86.123.127.8", but my machine IP address is a bit different. How does Stack Overflow get this address?

例如,在 Stack Overflow 用户配置文件中,它是:"Last account activity: 4 hours ago from 86.123.127.8",但我的机器 IP 地址有点不同。Stack Overflow 是如何得到这个地址的?

In some web systems there is an IP address check for some purposes. For example, with a certain IP address, for every 24 hours can the user just have only 5 clicks on download links? This IP address should be unique, not for an ISP that has a huge range of clients or Internet users.

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

Did I understand well?

我理解得好吗?

采纳答案by Steve

As others have said you can't do what you are asking. If you describe the problem you are trying to solve maybe someone can help?

正如其他人所说,你不能做你所要求的。如果您描述了您要解决的问题,也许有人可以提供帮助?

E.g.

例如

  • are you trying to uniquely identify your users?
  • Could you use a cookie, or the session ID perhaps instead of the IP address?
  • 您是否正在尝试唯一标识您的用户?
  • 您可以使用 cookie 或会话 ID 来代替 IP 地址吗?

EditThe 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.

编辑您在服务器上看到的地址不应该是 ISP 的地址,正如您所说,这将是一个很大的范围。宽带上的家庭用户的地址将是其路由器上的地址,因此屋内的每个设备在外面看起来都是相同的,但路由器使用 NAT 来确保流量正确路由到每个设备。对于从办公环境访问的用户,所有用户的地址很可能是相同的。使用 IP 地址作为 ID 的站点冒着将其弄错的风险 - 您提供的示例很好,但它们经常失败。例如,我的办公室在英国,突破点(我“似乎”在互联网上的位置)在我们主要 IT 设施所在的另一个国家/地区,因此从我的办公室看,我的 IP 地址似乎不在英国。出于这个原因,我无法访问仅限英国的网络内容,例如 BBC iPlayer)。在任何时候,我公司都会有数百甚至数千人似乎从同一个 IP 地址访问网络。

When you are writing server code you can never be sure what the IP address you see is referring to. Some users like it this way. Some people deliberately use a proxy or VPN to further confound you.

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

When you say your machine address is different to the IP address shown on StackOverflow, how are you finding out your machine address? If you are just looking locally using ipconfigor something like that I would expect it to be different for the reasons I outlined above. If you want to double check what the outside world thinks have a look at whatismyipaddress.com/.

当您说您的机器地址与 StackOverflow 上显示的 IP 地址不同时,您是如何找到您的机器地址的?如果您只是在本地使用ipconfig或类似的东西,我希望它会因我上面概述的原因而有所不同。如果您想仔细检查外界的看法,请查看whatismyipaddress.com/

This Wikipedia link on NATwill provide you some background on this.

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

回答by Mehrdad Afshari

What else do you consider the user IP address? If you want the IP address of the network adapter, I'm afraid there's no possible way to do it in a Web app. If your user is behind NAT or other stuff, you can't get the IP either.

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

Update: While there are Web sites that use IP to limit the user (like rapidshare), they don't work correctly in NAT environments.

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

回答by John Saunders

IP addresses are part of the Network layer in the "seven-layer stack". The Network layer can do whatever it wants to do with the IP address. That's what happens with a proxy server, NAT, relay, or whatever.

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

The Application layer should not depend on the IP address in any way. In particular, an IP Address is not meant to be an identifier of anything other than the idenfitier of one end of a network connection. As soon as a connection is closed, you should expect the IP address (of the same user) to change.

应用层不应以任何方式依赖 IP 地址。尤其是,IP 地址并不是网络连接一端的标识符以外的任何标识符。一旦连接关闭,您应该期望(同一用户的)IP 地址发生变化。

回答by mangokun

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.

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

Here's why...

这就是为什么...

Sometimes your visitors are behind either a proxy server or a router and the standard Request.UserHostAddressonly 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").

有时,您的访问者位于代理服务器或路由器后面,而标准Request.UserHostAddress仅捕获代理服务器或路由器的 IP 地址。在这种情况下,用户的 IP 地址将存储在服务器变量(“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").

所以我们想要做的是首先检查“HTTP_X_FORWARDED_FOR”,如果它是空的,我们就简单地返回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"

虽然这种方法不是万无一失的,但它可以带来更好的结果。下面是 VB.NET 中的 ASP.NET 代码,摘自James Crowley 的博客文章“Gotcha: HTTP_X_FORWARDED_FOR 返回多个 IP 地址”

C#

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.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

回答by Shahid

What you can do is store the router IP of your user and also the forwarded IP and try to make it reliable using both the IPs [External Public and Internal Private]. But again after some days client may be assigned new internal IP from router but it will be more reliable.

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

回答by Bat_Programmer

You can use:

您可以使用:

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

回答by algreat

UPDATE:Thanks to Bruno Lopes. If several ip addresses could come then need to use this method:

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

回答by user1657913

use this

用这个

Dns.GetHostEntry(Dns.GetHostName())

回答by KMX

I think I should share my experience with you all. Well I see in some situations REMOTE_ADDRwill NOT get you what you are looking for. For instance, if you have a Load Balancer behind the scene and if you are trying to get the Client's IP then you will be in trouble. I checked it with my IP masking software plus I also checked with my colleagues being in different continents. So here is my solution.

我觉得我应该和大家分享一下我的经验。好吧,我看到在某些情况下REMOTE_ADDR不会让你得到你想要的东西。例如,如果您在后台有一个负载均衡器,并且您试图获取客户端的 IP,那么您将遇到麻烦。我用我的 IP 掩码软件进行了检查,并且还与我在不同大陆的同事进行了检查。所以这是我的解决方案。

When I want to know the IP of a client, I try to pick every possible evidence so I could determine if they are unique:

当我想知道客户端的 IP 时,我会尝试挑选所有可能的证据,以便确定它们是否是唯一的:

Here I found another sever-var that could help you all if you want to get exact IP of the client side. so I am using : HTTP_X_CLUSTER_CLIENT_IP

在这里,我找到了另一个 sever-var,如果您想获得客户端的确切 IP,它可以帮助大家。所以我使用:HTTP_X_CLUSTER_CLIENT_IP

HTTP_X_CLUSTER_CLIENT_IPalways gets you the exact IP of the client. In any case if its not giving you the value, you should then look for HTTP_X_FORWARDED_FORas it is the second best candidate to get you the client IP and then the REMOTE_ADDRvar which may or may not return you the IP but to me having all these three is what I find the best thing to monitor them.

HTTP_X_CLUSTER_CLIENT_IP始终为您提供客户端的确切 IP。在任何情况下,如果它没有为您提供价值,那么您应该寻找HTTP_X_FORWARDED_FOR因为它是第二个最佳候选者,可以为您提供客户端 IP,然后是REMOTE_ADDR变量,它可能会或可能不会返回您的 IP,但对我来说拥有所有这些三是我觉得最好的东西就是监控它们。

I hope this helps some guys.

我希望这可以帮助一些人。

回答by Juan David Nicholls Cardona

If is c# see this way, is very simple

如果是c#看这个方式,很简单

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