Как можно предотвратить множество запросов клиента к веб-API (c#)? - PullRequest
0 голосов
/ 04 марта 2020

Я хочу остановить клиента, когда, например, на сервер отправлено много запросов, 30 запросов за 10 секунд, и я хочу, чтобы он / она не мог отправить его до 10 минут. Это мой код, который я использую в качестве атрибута для каждого веб-API.

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class AllowXRequestsEveryXSecondsAttribute : ActionFilterAttribute
{

    public string Name { get; set; }


    public int Seconds { get; set; }

    public int MinutesLockUser { get; set; }


    public int Requests { get; set; }

    public string Message { get; set; }

    public string ContentName { get; set; }

      public class Int32Value
    {
        public Int32Value()
        {
            Value = 1;
        }
        public int Value { get; set; }
    }

    public override void OnActionExecuting(HttpActionContext c)
    {
        if (c == null) throw new ArgumentException("ActionExecutingContext not spcecified");
        this.Name = "AllowXrequestinXSecond";
        this.Seconds = 10;
        this.Requests = 30;

        string ipAddress = HttpContext.Current.Request.UserHostAddress;
        var key = string.Concat("AllowXRequestsEveryXSeconds-", Name, "-", ipAddress);

        var allowExecute = false;

        var currentCacheValue = HttpRuntime.Cache[key];
        if (currentCacheValue == null)
        {

            HttpRuntime.Cache.Add(key,
                new Int32Value(),
                null,// no dependencies
              Cache.NoAbsoluteExpiration,// absolute expiration
                TimeSpan.FromSeconds(Seconds),
                CacheItemPriority.Low,
                null); // no callback

            allowExecute = true;
        }
        else
        {

            var value = (Int32Value)currentCacheValue;
            value.Value++;


            if (value.Value <= Requests)
            {
                allowExecute = true;
            }



        }

        if (!allowExecute)
        {
            if (String.IsNullOrEmpty(Message))
              Message = "You have performed this action more than {x} Requests in the last {n} seconds.";

            if (((Int32Value)currentCacheValue).Value == Requests + 1)
            {

                Helpers.LogToDb(Message, key);
            }

            c.Response = c.Request.CreateResponse(
                HttpStatusCode.Conflict,
                Message.Replace("{n}", Seconds.ToString())
            );
             c.Response.StatusCode = HttpStatusCode.Conflict;
        }
    }


}

это хороший код, но у него есть проблема. он кэшируется на 10 секунд и после этого refre sh. Мне нужно заблокировать пользователя на 10 минут.

...