簡體   English   中英

如何在 ASP.NET MVC 站點中實施速率限制?

[英]How do I implement rate limiting in an ASP.NET MVC site?

我正在構建一個 ASP.NET MVC 站點,我想在其中限制經過身份驗證的用戶使用站點某些功能的頻率。

盡管我從根本上了解速率限制的工作原理,但我無法想象如何在不產生主要代碼味道的情況下以編程方式實現它。

能用 C# 示例代碼指出一個簡單而強大的解決方案來解決這個問題嗎?

如果重要的話,所有這些功能目前都表示為僅接受HTTP POST的操作。 我最終可能還想對HTTP GET函數實施速率限制,因此我正在尋找適用於所有此類情況的解決方案。

如果您使用的是IIS 7,則可以查看動態IP限制擴展 另一種可能性是將其實現為動作過濾器:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class RateLimitAttribute : ActionFilterAttribute
{
    public int Seconds { get; set; }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        // Using the IP Address here as part of the key but you could modify
        // and use the username if you are going to limit only authenticated users
        // filterContext.HttpContext.User.Identity.Name
        var key = string.Format("{0}-{1}-{2}",
            filterContext.ActionDescriptor.ControllerDescriptor.ControllerName,
            filterContext.ActionDescriptor.ActionName,
            filterContext.HttpContext.Request.UserHostAddress
        );
        var allowExecute = false;

        if (HttpRuntime.Cache[key] == null)
        {
            HttpRuntime.Cache.Add(key,
                true,
                null,
                DateTime.Now.AddSeconds(Seconds),
                Cache.NoSlidingExpiration,
                CacheItemPriority.Low,
                null);
            allowExecute = true;
        }

        if (!allowExecute)
        {
            filterContext.Result = new ContentResult
            {
                Content = string.Format("You can call this every {0} seconds", Seconds)
            };
            filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.Conflict;
        }
    }
}

然后裝飾需要限制的動作:

[RateLimit(Seconds = 10)]
public ActionResult Index()
{
    return View();
}

看看Jarrod關於他們如何在SO上做到這一點的答案。

StackOverflow MVC限制

一些示例代碼以及它如何工作的解釋。

.Net 6

看看這個:

Nuget: https://www.nuget.org/packages/DotNetRateLimiter/

很簡單:

[HttpGet("")]
[RateLimit(PeriodInSec = 60, Limit = 3)]
public IEnumerable<WeatherForecast> Get()
{
    ....
}

甚至你可以通過路由或查詢參數來控制請求:

[HttpGet("by-query/{id}")]
[RateLimit(PeriodInSec = 60, Limit = 3, RouteParams = "id", QueryParams = "name,family")]
public IEnumerable<WeatherForecast> Get(int id, string name, [FromQuery] List<string> family)
{
    ....
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM