আমি কীভাবে এএসপি.নেট এমভিসিতে ক্লায়েন্টের আইপি ঠিকানা পেতে পারি?


311

আমি এএসপি.নেট এমভিসি স্ট্যাকের জন্য সম্পূর্ণ নতুন এবং আমি ভাবছিলাম যে সরল পেজ অবজেক্ট এবং রিকোয়েস্ট সার্ভারভেয়ারেবলসের কী হবে?

মূলত, আমি ক্লায়েন্টের পিসির আইপি ঠিকানাটি টানতে চাই, তবে বর্তমান এমভিসি কাঠামো কীভাবে এই সমস্ত পরিবর্তন করেছে তা আমি বুঝতে ব্যর্থ হয়েছি।

আমি যতদূর বুঝতে পারি, বেশিরভাগ ভেরিয়েবল অবজেক্ট HtpPequest ভেরিয়েন্ট দ্বারা প্রতিস্থাপিত হয়েছে

কেউ কি কিছু সম্পদ ভাগ করে নেওয়ার চিন্তা করে? এএসপি.এনইটি এমভিসি ওয়ার্ল্ডে শেখার জন্য সত্যই জিনিসগুলির একটি সমুদ্র রয়েছে। :)

উদাহরণস্বরূপ, আমার এই বর্তমান ফাংশন সহ একটি স্ট্যাটিক ক্লাস রয়েছে। আমি এএসপি.নেট এমভিসি ব্যবহার করে কীভাবে একই ফলাফল পেতে পারি?

public static int getCountry(Page page)
{
    return getCountryFromIP(getIPAddress(page));
}

public static string getIPAddress(Page page)
{
    string szRemoteAddr = page.Request.ServerVariables["REMOTE_ADDR"];
    string szXForwardedFor = page.Request.ServerVariables["X_FORWARDED_FOR"];
    string szIP = "";

    if (szXForwardedFor == null)
    {
        szIP = szRemoteAddr;
    }
    else
    {
        szIP = szXForwardedFor;

        if (szIP.IndexOf(",") > 0)
        {
            string [] arIPs = szIP.Split(',');

            foreach (string item in arIPs)
            {
                if (!isPrivateIP(item))
                {
                    return item;
                }
            }
        }
    }
    return szIP;
}

এবং আমি কন্ট্রোলার পৃষ্ঠা থেকে এই ফাংশনটি কল করব?



উত্তর:


427

সহজ উত্তরটি হ'ল HTTPRequest.UserHostAddress সম্পত্তিটি ব্যবহার করা ।

উদাহরণ: একটি নিয়ামকের মধ্যে থেকে:

using System;
using System.Web.Mvc;

namespace Mvc.Controllers
{
    public class HomeController : ClientController
    {
        public ActionResult Index()
        {
            string ip = Request.UserHostAddress;

            ...
        }
    }
}

উদাহরণ: সাহায্যকারী শ্রেণীর মধ্যে থেকে:

using System.Web;

namespace Mvc.Helpers
{
    public static class HelperClass
    {
        public static string GetIPHelper()
        {
            string ip = HttpContext.Current.Request.UserHostAddress;
            ..
        }
    }
}

কিন্তু, যদি অনুরোধটি এক বা একাধিক, প্রক্সি সার্ভার দ্বারা প্রেরণ করা হয়ে থাকে তবে এইচটিপিআরকুয়েস্টের দ্বারা ফিরে আসা আইপি ঠিকানা ser ইউজারহোস্টএড্রেস সম্পত্তি হ'ল অনুরোধটি রিলে করেছে এমন সর্বশেষ প্রক্সি সার্ভারের আইপি ঠিকানা হবে।

প্রক্সি সার্ভার পারে ব্যবহার কার্যত ক্লায়েন্ট সিস্টেমের IP ঠিকানা স্থাপন মান এক্স-ফরোয়ার্ড করা-জন্য HTTP শিরোলেখ। এক্ষেত্রে কোনও অনুরোধের এক্স-ফরওয়ার্ড-ফর শিরোনাম রয়েছে এমন কোনও গ্যারান্টি নেই, এক্স-ফরওয়ার্ড-ফর স্পোস করা হয়নি এমন কোনও গ্যারান্টিও নেই ।


আসল উত্তর

Request.UserHostAddress

উপরের কোডটি কোনও সংগ্রহ অনুসন্ধান না করেই ক্লায়েন্টের আইপি ঠিকানা সরবরাহ করে। অনুরোধ সম্পত্তি নিয়ন্ত্রণকারীদের (বা দর্শন) এর মধ্যে উপলব্ধ। অতএব আপনার ফাংশনে পৃষ্ঠার ক্লাসটি পাস করার পরিবর্তে আপনি একই ফলাফল পেতে অনুরোধ অবজেক্টটি পাস করতে পারেন:

public static string getIPAddress(HttpRequestBase request)
{
    string szRemoteAddr = request.UserHostAddress;
    string szXForwardedFor = request.ServerVariables["X_FORWARDED_FOR"];
    string szIP = "";

    if (szXForwardedFor == null)
    {
        szIP = szRemoteAddr;
    }
    else
    {
        szIP = szXForwardedFor;
        if (szIP.IndexOf(",") > 0)
        {
            string [] arIPs = szIP.Split(',');

            foreach (string item in arIPs)
            {
                if (!isPrivateIP(item))
                {
                    return item;
                }
            }
        }
    }
    return szIP;
}

6
@ makerofthings7: একাধিক মান থাকতে পারে কারণ একাধিক প্রক্সি সার্ভার ক্লায়েন্টের এইচটিটিপি অনুরোধের সাথে ফরোয়ার্ড করতে পারে। যদি প্রক্সি সার্ভারগুলি "ভাল আচরণ করা হয়" (ইচ্ছাকৃতভাবে বেনামে প্রক্সির বিপরীতে বা কেবল খারাপভাবে প্রোগ্রাম করা হয়েছে), প্রতিটি এক্সএফএফ শিরোনামে পূর্বের আইপিটি ব্যবহার করবে।
এরিক জে।

14
IsprivateIP পদ্ধতিটি কী করে?
এডিগ্রোভস

19
":: 1" এর অর্থ লোকালহোস্ট। শুধু একটি সহজ নোট।
tomg

5
এক্স-ফরওয়ার্ডেড-ফর শিরোনাম ফায়ারওয়াল এবং লোড ব্যালান্সার যুক্ত করেছে যা প্যাকেট বিশ্লেষণ করে মাঝখানে একজন মানুষ হিসাবে কাজ করে। মূল ব্যবহারকারীর আইপি ঠিকানা সংরক্ষণের জন্য এই শিরোনামটি যুক্ত করা হয়েছে যাতে মূল তথ্যটি পুনরুদ্ধার করা যায়। প্যাকেটটি নতুন করে লিখলে নতুন আইপি ঠিকানাটি সাধারণত একটি অভ্যন্তরীণ আইপি হয় এবং খুব কার্যকর হয় না।
মার্কো

2
আপনাকে ধন্যবাদ, এটি আমাকে সাহায্য করেছিল।
জ্যাক ফেয়ারফিল্ড

168

Request.ServerVariables["REMOTE_ADDR"] কাজ করা উচিত - হয় প্রত্যক্ষ দৃষ্টিতে বা নিয়ামক অ্যাকশন পদ্ধতিতে (অনুরোধ পৃষ্ঠাতে নয়, এমভিসিতে নিয়ন্ত্রক শ্রেণীর একটি সম্পত্তি)।

এটি কাজ করছে .. তবে আপনাকে ভার্চুয়াল নয়, আসল আইআইএসে প্রকাশ করতে হবে।


আমি কন্ট্রোলার পক্ষ থেকে এই কল কিভাবে?
মেলাওস

হ্যাঁ, ওহে যে কাজ করে, আমি কি উপরের মত একটি বর্গ বস্তুর মধ্যে রাখতে চান তা হলে কি হবে? এবং আমি কি এখনও পৃষ্ঠা অবজেক্টের প্রয়োজন?
মেলাওস

11
আমি মনে করি আপনি HTTPContext.Current.Request
ওভোকো

23
অ্যাড্রিয়ান এর উত্তর (নীচে) অনেক ভাল - এটি যাদু স্ট্রিং দ্বারা একটি অনুসন্ধানের প্রয়োজন হয় না। অনুরোধটি ব্যবহার করুন ser
উক্তর

এটি সর্বদা আমার অ্যাপ্লিকেশনটি চালিত সার্ভারের আইপি ঠিকানা প্রদান করে। কোন কারণে কেন?
জ্যাক মার্কেটি

101

এখানে প্রচুর কোডগুলি খুব সহায়ক ছিল, তবে আমি এটি আমার উদ্দেশ্যে এটি পরিষ্কার করে দিয়েছি এবং কিছু পরীক্ষা যুক্ত করেছি। আমি এখানে যা শেষ করেছি তা এখানে:

using System;
using System.Linq;
using System.Net;
using System.Web;

public class RequestHelpers
{
    public static string GetClientIpAddress(HttpRequestBase request)
    {
        try
        {
            var userHostAddress = request.UserHostAddress;

            // Attempt to parse.  If it fails, we catch below and return "0.0.0.0"
            // Could use TryParse instead, but I wanted to catch all exceptions
            IPAddress.Parse(userHostAddress);

            var xForwardedFor = request.ServerVariables["X_FORWARDED_FOR"];

            if (string.IsNullOrEmpty(xForwardedFor))
                return userHostAddress;

            // Get a list of public ip addresses in the X_FORWARDED_FOR variable
            var publicForwardingIps = xForwardedFor.Split(',').Where(ip => !IsPrivateIpAddress(ip)).ToList();

            // If we found any, return the last one, otherwise return the user host address
            return publicForwardingIps.Any() ? publicForwardingIps.Last() : userHostAddress;
        }
        catch (Exception)
        {
            // Always return all zeroes for any failure (my calling code expects it)
            return "0.0.0.0";
        }
    }

    private static bool IsPrivateIpAddress(string ipAddress)
    {
        // http://en.wikipedia.org/wiki/Private_network
        // Private IP Addresses are: 
        //  24-bit block: 10.0.0.0 through 10.255.255.255
        //  20-bit block: 172.16.0.0 through 172.31.255.255
        //  16-bit block: 192.168.0.0 through 192.168.255.255
        //  Link-local addresses: 169.254.0.0 through 169.254.255.255 (http://en.wikipedia.org/wiki/Link-local_address)

        var ip = IPAddress.Parse(ipAddress);
        var octets = ip.GetAddressBytes();

        var is24BitBlock = octets[0] == 10;
        if (is24BitBlock) return true; // Return to prevent further processing

        var is20BitBlock = octets[0] == 172 && octets[1] >= 16 && octets[1] <= 31;
        if (is20BitBlock) return true; // Return to prevent further processing

        var is16BitBlock = octets[0] == 192 && octets[1] == 168;
        if (is16BitBlock) return true; // Return to prevent further processing

        var isLinkLocalAddress = octets[0] == 169 && octets[1] == 254;
        return isLinkLocalAddress;
    }
}

এবং সেই কোডটির বিপরীতে এখানে কিছু নুনিট পরীক্ষা রয়েছে (আমি এইচটিপিআরকুয়েস্টবেসকে উপহাস করার জন্য রাইনো মোকস ব্যবহার করছি, যা নীচে এম <HttpRequestBase> কল রয়েছে):

using System.Web;
using NUnit.Framework;
using Rhino.Mocks;
using Should;

[TestFixture]
public class HelpersTests : TestBase
{
    HttpRequestBase _httpRequest;

    private const string XForwardedFor = "X_FORWARDED_FOR";
    private const string MalformedIpAddress = "MALFORMED";
    private const string DefaultIpAddress = "0.0.0.0";
    private const string GoogleIpAddress = "74.125.224.224";
    private const string MicrosoftIpAddress = "65.55.58.201";
    private const string Private24Bit = "10.0.0.0";
    private const string Private20Bit = "172.16.0.0";
    private const string Private16Bit = "192.168.0.0";
    private const string PrivateLinkLocal = "169.254.0.0";

    [SetUp]
    public void Setup()
    {
        _httpRequest = M<HttpRequestBase>();
    }

    [TearDown]
    public void Teardown()
    {
        _httpRequest = null;
    }

    [Test]
    public void PublicIpAndNullXForwardedFor_Returns_CorrectIp()
    {
        // Arrange
        _httpRequest.Stub(x => x.UserHostAddress).Return(GoogleIpAddress);
        _httpRequest.Stub(x => x.ServerVariables[XForwardedFor]).Return(null);

        // Act
        var ip = RequestHelpers.GetClientIpAddress(_httpRequest);

        // Assert
        ip.ShouldEqual(GoogleIpAddress);
    }

    [Test]
    public void PublicIpAndEmptyXForwardedFor_Returns_CorrectIp()
    {
        // Arrange
        _httpRequest.Stub(x => x.UserHostAddress).Return(GoogleIpAddress);
        _httpRequest.Stub(x => x.ServerVariables[XForwardedFor]).Return(string.Empty);

        // Act
        var ip = RequestHelpers.GetClientIpAddress(_httpRequest);

        // Assert
        ip.ShouldEqual(GoogleIpAddress);
    }

    [Test]
    public void MalformedUserHostAddress_Returns_DefaultIpAddress()
    {
        // Arrange
        _httpRequest.Stub(x => x.UserHostAddress).Return(MalformedIpAddress);
        _httpRequest.Stub(x => x.ServerVariables[XForwardedFor]).Return(null);

        // Act
        var ip = RequestHelpers.GetClientIpAddress(_httpRequest);

        // Assert
        ip.ShouldEqual(DefaultIpAddress);
    }

    [Test]
    public void MalformedXForwardedFor_Returns_DefaultIpAddress()
    {
        // Arrange
        _httpRequest.Stub(x => x.UserHostAddress).Return(GoogleIpAddress);
        _httpRequest.Stub(x => x.ServerVariables[XForwardedFor]).Return(MalformedIpAddress);

        // Act
        var ip = RequestHelpers.GetClientIpAddress(_httpRequest);

        // Assert
        ip.ShouldEqual(DefaultIpAddress);
    }

    [Test]
    public void SingleValidPublicXForwardedFor_Returns_XForwardedFor()
    {
        // Arrange
        _httpRequest.Stub(x => x.UserHostAddress).Return(GoogleIpAddress);
        _httpRequest.Stub(x => x.ServerVariables[XForwardedFor]).Return(MicrosoftIpAddress);

        // Act
        var ip = RequestHelpers.GetClientIpAddress(_httpRequest);

        // Assert
        ip.ShouldEqual(MicrosoftIpAddress);
    }

    [Test]
    public void MultipleValidPublicXForwardedFor_Returns_LastXForwardedFor()
    {
        // Arrange
        _httpRequest.Stub(x => x.UserHostAddress).Return(GoogleIpAddress);
        _httpRequest.Stub(x => x.ServerVariables[XForwardedFor]).Return(GoogleIpAddress + "," + MicrosoftIpAddress);

        // Act
        var ip = RequestHelpers.GetClientIpAddress(_httpRequest);

        // Assert
        ip.ShouldEqual(MicrosoftIpAddress);
    }

    [Test]
    public void SinglePrivateXForwardedFor_Returns_UserHostAddress()
    {
        // Arrange
        _httpRequest.Stub(x => x.UserHostAddress).Return(GoogleIpAddress);
        _httpRequest.Stub(x => x.ServerVariables[XForwardedFor]).Return(Private24Bit);

        // Act
        var ip = RequestHelpers.GetClientIpAddress(_httpRequest);

        // Assert
        ip.ShouldEqual(GoogleIpAddress);
    }

    [Test]
    public void MultiplePrivateXForwardedFor_Returns_UserHostAddress()
    {
        // Arrange
        _httpRequest.Stub(x => x.UserHostAddress).Return(GoogleIpAddress);
        const string privateIpList = Private24Bit + "," + Private20Bit + "," + Private16Bit + "," + PrivateLinkLocal;
        _httpRequest.Stub(x => x.ServerVariables[XForwardedFor]).Return(privateIpList);

        // Act
        var ip = RequestHelpers.GetClientIpAddress(_httpRequest);

        // Assert
        ip.ShouldEqual(GoogleIpAddress);
    }

    [Test]
    public void MultiplePublicXForwardedForWithPrivateLast_Returns_LastPublic()
    {
        // Arrange
        _httpRequest.Stub(x => x.UserHostAddress).Return(GoogleIpAddress);
        const string privateIpList = Private24Bit + "," + Private20Bit + "," + MicrosoftIpAddress + "," + PrivateLinkLocal;
        _httpRequest.Stub(x => x.ServerVariables[XForwardedFor]).Return(privateIpList);

        // Act
        var ip = RequestHelpers.GetClientIpAddress(_httpRequest);

        // Assert
        ip.ShouldEqual(MicrosoftIpAddress);
    }
}

2
এটি সর্বদা আমার অ্যাপ্লিকেশনটি চালিত সার্ভারের আইপি ঠিকানা প্রদান করে।
জ্যাক মার্চেটি

1
এটি কি ফেরত দেওয়া উচিত নয় publicForwardingIps.First()?
andy250

1
@ নোহাহ আমি অনুমান করছি এটি আইপিভি 6 ঠিকানাগুলির জন্য কাজ করবে না?
আইডানও

চমৎকার সমাধান! আইপিএড্রেস.পার্স () অন্যান্য আইপি ঠিকানায়ও ব্যবহার করা উচিত?
Co-der

21

উপরেরটি ব্যবহার করতে আমার সমস্যা হয়েছে, এবং আমার একটি নিয়ামকের আইপি ঠিকানা প্রয়োজন। আমি নিম্নলিখিতটি নিম্নলিখিতটি ব্যবহার করেছি:

System.Web.HttpContext.Current.Request.UserHostAddress

2
নিয়ন্ত্রক থেকে আপনাকে যা করতে হবে তা হ'লHttpContext.Request.UserHostAddress
সার্জ সাগান

ধন্যবাদ। সহায়ক বা ক্লাসে আমার যা প্রয়োজন তা কোনও নিয়ামক বা দর্শনের প্রসঙ্গে নয়। এটি একটি দুর্দান্ত সর্বজনীন উত্তর। +1
পাইওটার কুলা

@ গেন্ডার মানে কি? হো আমি কি বিবৃতি লিখি?
পাইওটর কুলা

1
সহায়ক শ্রেণীর শীর্ষে, কেবল "System.Web;" ব্যবহার করে লিখুন, তারপরে আপনাকে কেবল "HttpContext.Current.Request.UserHostAdress" লিখতে হবে। শুধু অলস প্রোগ্রামারদের জন্য, নিজের মতো করে (এবং কেন টমের জবাব এবং
সেরজের

19

একটি ক্লাসে আপনি এটি কল করতে পারেন:

public static string GetIPAddress(HttpRequestBase request) 
{
    string ip;
    try
    {
        ip = request.ServerVariables["HTTP_X_FORWARDED_FOR"];
        if (!string.IsNullOrEmpty(ip))
        {
            if (ip.IndexOf(",") > 0)
            {
                string[] ipRange = ip.Split(',');
                int le = ipRange.Length - 1;
                ip = ipRange[le];
            }
        } else
        {
            ip = request.UserHostAddress;
        }
    } catch { ip = null; }

    return ip; 
}

আমি দুর্দান্ত ফলাফল সহ একটি রেজার অ্যাপ্লিকেশনটিতে এটি ব্যবহার করেছি।


আপনি HTTP_X_FORWARDED_FOR থেকে শেষ ঠিকানাটি কেন ফেরৎ দেবেন? এটি কি ক্লায়েন্টের ঠিকানাটি প্রথম নয়?
ইগোর ইয়ালভয়

1

আমার সাইটটি অ্যামাজন এডাব্লুএস ইলাস্টিক লোড ব্যালান্সারের (ইএলবি) পিছনে থাকার জন্য আমি কীভাবে অ্যাকাউন্ট করব :

public class GetPublicIp {

    /// <summary>
    /// account for possbility of ELB sheilding the public IP address
    /// </summary>
    /// <returns></returns>
    public static string Execute() {
        try {
            Console.WriteLine(string.Join("|", new List<object> {
                    HttpContext.Current.Request.UserHostAddress,
                    HttpContext.Current.Request.Headers["X-Forwarded-For"],
                    HttpContext.Current.Request.Headers["REMOTE_ADDR"]
                })
            );

            var ip = HttpContext.Current.Request.UserHostAddress;
            if (HttpContext.Current.Request.Headers["X-Forwarded-For"] != null) {
                ip = HttpContext.Current.Request.Headers["X-Forwarded-For"];
                Console.WriteLine(ip + "|X-Forwarded-For");
            }
            else if (HttpContext.Current.Request.Headers["REMOTE_ADDR"] != null) {
                ip = HttpContext.Current.Request.Headers["REMOTE_ADDR"];
                Console.WriteLine(ip + "|REMOTE_ADDR");
            }
            return ip;
        }
        catch (Exception ex) {
            Console.Error.WriteLine(ex.Message);
        }
        return null;
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.