۲۹ شهریور ۱۴۰۳

Techboy

اخبار و اطلاعات روز تکنولوژی

نحوه استفاده از الگوریتم های محدود کننده نرخ در ASP.NET Core

یاد بگیرید که چگونه از پنجره ثابت، پنجره کشویی، سطل نشانه و الگوریتم های همزمان در ASP.NET Core 7 برای محافظت از برنامه ها و API های خود در برابر حملات مخرب یا استفاده بیش از حد استفاده کنید.

یاد بگیرید که چگونه از پنجره ثابت، پنجره کشویی، سطل نشانه و الگوریتم های همزمان در ASP.NET Core 7 برای محافظت از برنامه ها و API های خود در برابر حملات مخرب یا استفاده بیش از حد استفاده کنید.

محدود کردن نرخ تکنیکی است که برای محدود کردن تعداد درخواست‌های مجاز به یک منبع خاص در یک پنجره زمانی خاص برای خنثی کردن حملات DDoS و سوء استفاده‌های API استفاده می‌شود. هنگامی که به آستانه محدود کننده نرخ رسید، درخواست‌های بعدی به منبع غیرمجاز، به تأخیر افتاده یا کاهش می‌یابد.

در مقاله قبلی، درباره چگونگی شروع با میانافزار محدود کننده نرخ جدید در ASP.NET Core 7 بحث کردم. در این مقاله، چهار الگوریتم محدود کننده نرخ مختلف موجود در ASP.NET Core 7: پنجره ثابت، پنجره کشویی، سطل توکن و همزمانی.

برای استفاده از نمونه کدهای ارائه شده در این مقاله، باید Visual Studio 2022 را در سیستم خود نصب کنید. اگر قبلاً نسخه‌ای ندارید، می‌توانید Visual Studio 2022 را از اینجا بارگیری کنید.

یک پروژه ASP.NET Core minimal Web API در Visual Studio 2022 ایجاد کنید

ابتدا، اجازه دهید یک پروژه ASP.NET Core 7 حداقل Web API در Visual Studio 2022 ایجاد کنیم. این مراحل را دنبال کنید:

  1. Visual Studio 2022 IDE را راه اندازی کنید.
  2. روی “ایجاد پروژه جدید” کلیک کنید.
  3. در پنجره “ایجاد پروژه جدید”، “ASP.NET Core Web API” را از لیست الگوهای نمایش داده شده انتخاب کنید.
  4. بعدی را کلیک کنید.
  5. در پنجره “پیکربندی پروژه جدید خود”، نام و مکان پروژه جدید را مشخص کنید.
  6. به صورت اختیاری، بسته به تنظیمات برگزیده خود، کادر انتخاب «قرار دادن راه حل و پروژه در یک فهرست راهنمای» را علامت بزنید.
  7. بعدی را کلیک کنید.
  8. در پنجره “اطلاعات اضافی” که در ادامه نشان داده شده است، “NET 7.0 (Current)” را به عنوان چارچوب انتخاب کنید. تیک کادری که می‌گوید «استفاده از کنترل‌کننده‌ها…» را بردارید، زیرا در این مثال از حداقل API استفاده می‌کنیم. تنظیم «نوع احراز هویت» را روی «هیچ» (پیش‌فرض) بگذارید.
  9. مطمئن شوید که چک باکس‌های “Enable Docker”، “Configure for HTTPS” و “Enable Open Open API Support” همه علامت‌گذاری نشده باشند. ما در اینجا از هیچ یک از این ویژگی ها استفاده نخواهیم کرد.
  10. روی ایجاد کلیک کنید.

ما از این پروژه ASP.NET Core 7 Web API برای ایجاد یک API حداقل و پیاده‌سازی چهار الگوریتم محدودکننده نرخ مختلف در بخش‌های زیر استفاده خواهیم کرد.

یک کنترلر را در ASP.NET Core 7 پیاده سازی کنید

اجازه دهید یک کنترلر برای نشان دادن نحوه عملکرد محدود کردن نرخ در ASP.NET Core پیاده سازی کنیم. برای این کار پوشه Controllers solution پروژه خود را انتخاب کنید و سپس روی Add -> Controller کلیک کنید. الگوی “API Controller – Empty” را از لیست الگوهای نمایش داده شده در پنجره افزودن داربست انتخاب کنید و وقتی از شما خواسته شد نام برای کنترلر وارد کنید. سپس کد پیش فرض را با کد زیر جایگزین کنید.

    [Route("api/[controller]")]
    [ApiController]
    public class DefaultController : ControllerBase
    {
        [HttpGet]
        public string Get()
        {
            return "Hello World";
        }
        [HttpGet("{id}")]
        public string Get(int id)
        {
            return $"The value of id is: {id}";
        }
    }

کلاس پایه انتزاعی RateLimiter در ASP.NET Core 7

قبل از ASP.NET Core 7، محدودیت نرخ به عنوان بخشی از فضای نام Microsoft.AspNetCore.RateLimiting در دسترس بود. محدود کردن نرخ در ASP.NET Core 7 اکنون به عنوان بخشی از فضای نام System.Threading.RateLimiting در دسترس است.

5 روش QA برای ارزیابی تأثیر ابزارهای جدید تست هوش مصنوعی مولد

نوع اصلی کلاس پایه انتزاعی RateLimiter است که چندین ویژگی شگفت انگیز دارد. کلاس Abstract RateLimiter به شکل زیر است:

public abstract class RateLimiter : IAsyncDisposable, IDisposable
{
    public abstract RateLimiterStatistics? GetStatistics();
    public abstract TimeSpan? IdleDuration { get; }
    public RateLimitLease AttemptAcquire(int permitCount = 1);
    protected abstract RateLimitLease AttemptAcquireCore(int permitCount);
    public ValueTask<RateLimitLease> AcquireAsync(int permitCount = 1, CancellationToken cancellationToken = default);
    protected abstract ValueTask<RateLimitLease> AcquireAsyncCore(int permitCount, CancellationToken cancellationToken);
    protected virtual void Dispose(bool disposing);
    public void Dispose();
    protected virtual ValueTask DisposeAsyncCore();
    public async ValueTask DisposeAsync();
}

توجه داشته باشید که فقط اعلان های روش در اینجا ارائه شده است. تعاریف روش برای اختصار حذف شده است.

محدودیت نرخ را در ASP.NET Core 7 پیکربندی کنید

برای پیکربندی میان افزار محدود کننده نرخ در ASP.NET Core 7، از روش AddRateLimiter استفاده می کنید. برای افزودن میان‌افزار محدودکننده نرخ به برنامه ASP.NET Core 7 خود، ابتدا خدمات مورد نیاز را همانطور که در قطعه کد زیر نشان داده شده است، به ظرف اضافه می‌کنید.

builder.Services.AddRateLimiter(options =>{    //Write your code to configure the middleware here});

برای افزودن میان‌افزار به خط لوله، روش توسعه UseRateLimiter را مطابق شکل زیر فراخوانی می‌کنید.

app.UseRateLimiter(); 

می‌توانید RateLimiter را با چندین گزینه، از جمله حداکثر تعداد درخواست‌های مجاز، کد وضعیت پاسخ، و یک پنجره زمانی پیکربندی کنید. همچنین می توانید محدودیت نرخ را بر اساس روش HTTP، آدرس IP مشتری و سایر عوامل تعیین کنید. علاوه بر این، می‌توانید درخواست‌ها را به جای رد کردن در صف قرار دهید.

الگوریتم های محدود کننده نرخ در ASP.NET Core 7

بسته System.Threading.RateLimiting از مدل های الگوریتمی زیر پشتیبانی می کند:

  • پنجره ثابت
  • پنجره کشویی
  • سطل رمز
  • همزمان

پنجره ثابت

الگوریتم پنجره ثابت تعداد ثابتی از درخواست‌ها را در یک پنجره زمانی خاص اجازه می‌دهد، و تمام درخواست‌های بعدی حذف می‌شوند. این الگوریتم بر اساس نیاز محدود کننده نرخ، زمان را به پنجره های ثابت تقسیم می کند. به عنوان مثال، فرض کنید می خواهید ۱۰ درخواست در دقیقه را مجاز کنید. پس از رسیدن به این حد، درخواست‌های بعدی رد می‌شوند تا زمانی که پنجره بازنشانی شود.

توسعه‌دهندگان برای انعطاف‌پذیری، پشته فناوری در دنیای کاری ترکیبی ارزش قائل هستند

قطعه کد زیر نشان می دهد که چگونه می توانید محدود کننده نرخ پنجره ثابت را در فایل Program.cs در ASP.NET Core 7 پیکربندی کنید.

builder.Services.AddRateLimiter(options => {
    options.RejectionStatusCode = 429;
    options.AddFixedWindowLimiter(policyName: "fixed", options => {
        options.PermitLimit = 3;
        options.Window = TimeSpan.FromSeconds(10);
        options.AutoReplenishment = true;
        options.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
        options.QueueLimit = 2;
    });
});

روش AddLimiter برای افزودن سرویس‌های محدودکننده نرخ به ظرف خدمات استفاده می‌شود. روش AddFixedWindowLimiter برای افزودن یک خط مشی پنجره ثابت استفاده می شود. نام خط مشی در اینجا به عنوان “ثابت” مشخص شده است. به مقادیر ویژگی های PermitLimit و Window توجه کنید. با تنظیم PermitLimit روی ۳ و Window روی ۱۰، حداکثر سه درخواست را در هر ۱۰ ثانیه مجاز می‌کنید.

وقتی برنامه را اجرا می‌کنید و یک نقطه پایانی را بیشتر از حد مجاز فراخوانی می‌کنید، کد وضعیت HTTP 503 “سرویس در دسترس نیست” به طور پیش‌فرض برگردانده می‌شود. به سادگی RejectionStatusCode را تغییر دهید تا یک کد وضعیت متفاوت را بازگردانید. در مثال بالا، ویژگی RejectionStatusCode تنظیم شده است تا کد وضعیت HTTP 429 «درخواست‌های بیش از حد» را برگرداند.

به‌علاوه، QueueProcessingOrder به‌عنوان OldestFirst مشخص می‌شود، و QueueLimit روی ۲ تنظیم می‌شود. بنابراین، هر زمان که از محدودیت پنجره فراتر رفت، دو درخواست بعدی حذف و در یک صف ذخیره می‌شوند. سپس قدیمی ترین درخواست از صف انتخاب شده و پردازش می شود.

پنجره کشویی

مانند پنجره ثابت، الگوریتم پنجره کشویی تعداد ثابتی از درخواست ها را در هر پنجره زمانی امکان پذیر می کند. تفاوت این است که یک پنجره کشویی پنجره زمانی را به بخش هایی تقسیم می کند. در هر بازه از یک بخش، پنجره به اندازه یک بخش اسلاید می شود.

فاصله بخش برابر است با زمان پنجره تقسیم بر تعداد بخش در هر پنجره. بنابراین اگر پنجره شما ۶۰ ثانیه باشد و دو بخش را مشخص کنید، پنجره زمانی هر ۳۰ ثانیه یکبار کشویی می‌شود.

قطعه کد زیر نشان می دهد که چگونه می توانید محدود کننده نرخ پنجره کشویی را در فایل Program.cs در ASP.NET Core 7 پیکربندی کنید.

builder.Services.AddRateLimiter(options => {
    options.RejectionStatusCode = 429;
    options.AddSlidingWindowLimiter(policyName: "sliding", options => {
        options.PermitLimit = 30;
        options.Window = TimeSpan.FromSeconds(60);
        options.SegmentsPerWindow = 2;
        options.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
        options.QueueLimit = 2;
    });
});

ویژگی SegmentsPerWindow برای تعیین تعداد بخش ها در پنجره زمانی استفاده می شود.

سطل نشانه

در الگوریتم سطل نشانه، هر نشانه در سطل یک درخواست را نشان می دهد. هر زمان که درخواستی ارائه شود، یک توکن از سطل حذف می شود. اگر سطل خالی شود، درخواست بعدی رد می شود یا در گاز گرفته می شود. با گذشت زمان، سطل با نرخ ثابت دوباره پر می شود.

16 نوآوری غیر قابل مقاومت در ابر

مثالی را در نظر بگیرید که در آن یک سطل دارای محدودیت ۱۰ توکن است. هنگامی که یک درخواست وارد می شود و یک رمز در دسترس است، درخواست ارائه می شود و تعداد توکن ها کاهش می یابد. اگر از حد مجاز توکن فراتر رود و هیچ نشانه ای باقی نمانده باشد، درخواست ها رد می شوند یا کاهش می یابند.

نمونه کد زیر نشان می‌دهد که چگونه می‌توانید محدودکننده نرخ رمز را در فایل Program.cs در ASP.NET Core 7 پیکربندی کنید.

builder.Services.AddRateLimiter(options => {
    options.RejectionStatusCode = 429;
    options.AddTokenBucketLimiter(policyName: "token", options => {
        options.TokenLimit = 2;
        options.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
        options.QueueLimit = 2;
        options.ReplenishmentPeriod = TimeSpan.FromSeconds(10);
        options.TokensPerPeriod = 2;
        options.AutoReplenishment = true;
    });
});

ویژگی TokenLimit حداکثر تعداد نشانه هایی را که سطل می تواند در هر زمان معین ذخیره کند، مشخص می کند.

همزمان

یک محدودکننده همزمانی حداکثر تعداد درخواست‌های همزمان به یک منبع را کنترل می‌کند. به عنوان مثال، اگر محدودیتی ۱۰ تعیین کنید، فقط به ۱۰ درخواست اول در یک زمان معین به منبع دسترسی داده می شود. هر زمان که یک درخواست تکمیل شود، یک شکاف برای یک درخواست جدید باز می کند.

قطعه کد زیر نشان می دهد که چگونه می توانید محدود کننده نرخ همزمانی را در ASP.NET Core 7 پیکربندی کنید.

builder.Services.AddRateLimiter(options => {
    options.RejectionStatusCode = 429;
    options.AddConcurrencyLimiter(policyName: "concurrency", options => {
        options.PermitLimit = 3;
        options.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
        options.QueueLimit = 2;
    });
});

محدود کردن نرخ را در ASP.NET Core 7 فعال یا غیرفعال کنید

می توانید محدودیت نرخ را برای یک کنترلر، یک روش عمل یا صفحه Razor اعمال کنید. ویژگی‌های [EnableRateLimiting] و [DisableRateLimiting] را می‌توان برای فعال یا غیرفعال کردن محدودیت نرخ در ASP.NET Core 7 استفاده کرد.

لیست کد زیر نشان می‌دهد که چگونه می‌توانید محدودکننده نرخ «ثابت» را به DefaultController که قبلاً ایجاد کردیم اعمال کنید و محدود کردن نرخ را در یک روش عملی از همان کنترل‌کننده غیرفعال کنید.

    [Route("api/[controller]")]
    [ApiController]
    [EnableRateLimiting("fixed")]
    public class DefaultController : ControllerBase
    {
        [HttpGet]
        public string Get()
        {
            return "Hello World";
        }
        [HttpGet("{id}")]
        [DisableRateLimiting]
        public string Get(int id)
        {
            return $"The value of id is: {id}";
        }
    }

محدود کردن نرخ دارای چندین مزیت است. می تواند از برنامه ها یا API های شما در برابر انکار سرویس و سایر حملات مخرب و همچنین از استفاده بیش از حد غیر مخرب محافظت کند. با کاهش حجم درخواست‌ها در یک پنجره زمانی خاص و در نتیجه کاهش ترافیک شبکه و کاهش هزینه‌های زیرساختی. در نهایت، حتی می‌تواند با اطمینان از استفاده منصفانه از منابع موجود، عملکرد برنامه شما را بهبود بخشد.

در مقاله بعدی در مورد این موضوع، در مورد نحوه اجرای سیاست های محدود کننده نرخ سفارشی در ASP.NET Core 7 بحث خواهم کرد.