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

前端 未结 19 2544
时光取名叫无心
时光取名叫无心 2020-11-22 00:26

We have Request.UserHostAddress to 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

相关标签:
19条回答
  • 2020-11-22 00:42
    string IP = HttpContext.Current.Request.Params["HTTP_CLIENT_IP"] ?? HttpContext.Current.Request.UserHostAddress;
    
    0 讨论(0)
  • 2020-11-22 00:42

    use in ashx file

    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"];
    }
    
    0 讨论(0)
  • 2020-11-22 00:45

    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.

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

    0 讨论(0)
  • 2020-11-22 00:46

    All of the responses so far take into account the non-standardized, but very common, X-Forwarded-For header. There is a standardized Forwarded header which is a little more difficult to parse out. Some examples are as follows:

    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
    

    I have written a class that takes both of these headers into account when determining a client's IP address.

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

    Below are some unit tests that I used to validate my solution:

    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; }
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-22 00:47

    I think I should share my experience with you all. Well I see in some situations REMOTE_ADDR will 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.

    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:

    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

    HTTP_X_CLUSTER_CLIENT_IP always 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_FOR as it is the second best candidate to get you the client IP and then the REMOTE_ADDR var 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.

    I hope this helps some guys.

    0 讨论(0)
  • 2020-11-22 00:47

    Its easy.Try it:

    var remoteIpAddress = Request.HttpContext.Connection.RemoteIpAddress;
    

    just it :))

    0 讨论(0)
提交回复
热议问题