c# - ASP.NET में उपयोगकर्ता का क्लाइंट आईपी पता कैसे प्राप्त करें?




client ip-address (11)

हमारे पास ASP.NET में आईपी पता प्राप्त करने के लिए Request.UserHostAddress है, लेकिन यह आमतौर पर उपयोगकर्ता का आईएसपी का आईपी पता होता है, न कि उपयोगकर्ता के मशीन आईपी पते पर, उदाहरण के लिए एक लिंक पर क्लिक किया जाता है। मैं असली आईपी पता कैसे प्राप्त कर सकता हूं?

उदाहरण के लिए, एक स्टैक ओवरफ़्लो उपयोगकर्ता प्रोफ़ाइल में यह है: "अंतिम खाता गतिविधि: 86.123.127.8 से 4 घंटे पहले" , लेकिन मेरा मशीन आईपी पता थोड़ा अलग है। स्टैक ओवरफ़्लो इस पते को कैसे प्राप्त करता है?

कुछ वेब सिस्टम में कुछ उद्देश्यों के लिए एक आईपी पता जांच है। उदाहरण के लिए, एक निश्चित आईपी पते के साथ, हर 24 घंटों के लिए उपयोगकर्ता को डाउनलोड लिंक पर केवल 5 क्लिक ही मिल सकते हैं? यह आईपी पता अद्वितीय होना चाहिए, न कि एक आईएसपी के लिए जिसमें ग्राहकों या इंटरनेट उपयोगकर्ताओं की एक बड़ी श्रृंखला है।

क्या मैं अच्छी तरह से समझ गया?


अक्सर आप अपनी वेबसाइट पर आने वाले किसी के आईपी पते को जानना चाहेंगे। जबकि एएसपी.नेट के पास यह देखने के कई तरीके हैं कि हमने देखा है कि सर्वरवारीबल्स संग्रह के "HTTP_X_FORWARDED_FOR" का उपयोग करके हमने देखा है।

यहाँ पर क्यों...

कभी-कभी आपके विज़िटर या तो प्रॉक्सी सर्वर या राउटर के पीछे होते हैं और मानक Request.UserHostAddress केवल प्रॉक्सी सर्वर या राउटर के आईपी पते को कैप्चर करता है। जब ऐसा होता है तो उपयोगकर्ता का आईपी पता सर्वर चर ("HTTP_X_FORWARDED_FOR") में संग्रहीत किया जाता है।

तो हम क्या करना चाहते हैं सबसे पहले "HTTP_X_FORWARDED_FOR" जांचें और यदि वह खाली है तो हम बस ServerVariables("REMOTE_ADDR")

हालांकि यह विधि मूर्खतापूर्ण नहीं है, यह बेहतर परिणाम का कारण बन सकती है। नीचे जेम्स क्रॉली के ब्लॉग पोस्ट "गोचा: HTTP_X_FORWARDED_FOR से कई आईपी पते लौटाए गए वीबीएनईटी में एएसपी.नेट कोड है "

सी#

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

अब तक सभी प्रतिक्रियाएं गैर-मानकीकृत, लेकिन बहुत आम, X-Forwarded-For हेडर के 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

मैंने एक क्लास लिखा है जो क्लाइंट के आईपी पते का निर्धारण करते समय इन दोनों शीर्षकों को ध्यान में रखता है।

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

आप उपयोग कर सकते हैं:

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

आप उपयोगकर्ता आईपी पते पर और क्या विचार करते हैं? यदि आप नेटवर्क एडाप्टर का आईपी पता चाहते हैं, तो मुझे डर है कि वेब ऐप में ऐसा करने का कोई भी संभावित तरीका नहीं है। यदि आपका उपयोगकर्ता एनएटी या अन्य सामान के पीछे है, तो आप आईपी भी नहीं प्राप्त कर सकते हैं।

अपडेट करें : हालांकि ऐसी वेबसाइटें हैं जो उपयोगकर्ता को सीमित करने के लिए आईपी का उपयोग करती हैं (जैसे तेजी से), वे एनएटी वातावरण में सही ढंग से काम नहीं करते हैं।


इसे इस्तेमाल करो

Dns.GetHostEntry(Dns.GetHostName())

एएसएक्स फ़ाइल में प्रयोग करें

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

मुझे लगता है कि मुझे आपके साथ अपना अनुभव साझा करना चाहिए। खैर मैं कुछ स्थितियों में देखता हूं REMOTE_ADDR आपको वह नहीं मिलेगा जो आप खोज रहे हैं। उदाहरण के लिए, यदि आपके पास दृश्य के पीछे लोड बैलेंसर है और यदि आप क्लाइंट के आईपी को प्राप्त करने का प्रयास कर रहे हैं तो आप परेशानी में होंगे। मैंने इसे अपने आईपी मास्किंग सॉफ़्टवेयर के साथ चेक किया है और साथ ही मैंने अपने सहयोगियों के साथ विभिन्न महाद्वीपों में भी जांच की है। तो मेरा समाधान यहाँ है।

जब मैं किसी ग्राहक के आईपी को जानना चाहता हूं, तो मैं हर संभव सबूत लेने की कोशिश करता हूं ताकि मैं यह निर्धारित कर सकूं कि वे अद्वितीय हैं या नहीं:

यहां मुझे एक और सेवर-var मिला जो आपको सभी की मदद कर सकता है यदि आप क्लाइंट साइड के सटीक आईपी प्राप्त करना चाहते हैं। इसलिए मैं इसका उपयोग कर रहा हूं: HTTP_X_CLUSTER_CLIENT_IP

HTTP_X_CLUSTER_CLIENT_IP हमेशा आपको क्लाइंट का सटीक आईपी प्राप्त करता है। किसी भी मामले में यदि यह आपको मूल्य नहीं दे रहा है, तो आपको HTTP_X_FORWARDED_FOR की तलाश करनी चाहिए क्योंकि यह आपको क्लाइंट आईपी प्राप्त करने वाला दूसरा सबसे अच्छा उम्मीदवार है और फिर REMOTE_ADDR var जो आपको आईपी वापस कर सकता है या नहीं, लेकिन इन सभी को मेरे पास तीन मुझे उन पर नजर रखने के लिए सबसे अच्छी चीज मिलती है।

मुझे आशा है कि यह कुछ लोगों की मदद करेगा।


यदि आप क्लाउडफ्लारे का उपयोग कर रहे हैं, तो आप इस एक्सटेंशन विधि को आजमा सकते हैं:

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

फिर

string IPAddress = Request.GetIPAddress();

@Tony और @mangokun @Tony के उत्तरों का संयोजन, मैंने निम्नलिखित विस्तार विधि बनाई है:

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

अद्यतन: ब्रूनो लोपस के लिए धन्यवाद। यदि कई आईपी पते आ सकते हैं तो इस विधि का उपयोग करने की आवश्यकता है:

    private string GetUserIP()
    {
        string ipList = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];

        if (!string.IsNullOrEmpty(ipList))
        {
            return ipList.Split(',')[0];
        }

        return Request.ServerVariables["REMOTE_ADDR"];
    }

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




ip-address