在ASP.NET MVC下限制同一个IP地址单位时间间隔内的请求次数

有时候,当用户请求一个Controller下的Action,我们希望,在单位时间间隔内,比如每秒,每分钟,每小时,每天,每星期,限制同一个IP地址对某个Action的请求次数。如何做呢?

stefanprodan的MvcThrottle能很好地解决这个问题,以及其它类型的IP限制问题。在这里:https://github.com/stefanprodan/MvcThrottle

把项目从GitHub下载下来,在本地打开。

找到MvcThrottle类库,打开ThrottlingFilter这个类,在该类的OnActionExecuting方法中修改如下:

                        //check if limit is reached
                        if (rateLimit > 0 && throttleCounter.TotalRequests > rateLimit)
                        {
                            //log blocked request
                            if (Logger != null) Logger.Log(ComputeLogEntry(requestId, identity, throttleCounter, rateLimitPeriod.ToString(), rateLimit, filterContext.HttpContext.Request));

                            //break execution and return 409
                            var message = string.IsNullOrEmpty(QuotaExceededMessage) ?
                                "HTTP request quota exceeded! maximum admitted {0} per {1}" : QuotaExceededMessage;

                            //add status code and retry after x seconds to response
                            filterContext.HttpContext.Response.StatusCode = (int)QuotaExceededResponseCode;
                            filterContext.HttpContext.Response.Headers.Set("Retry-After", RetryAfterFrom(throttleCounter.Timestamp, rateLimitPeriod));

                            filterContext.Result = QuotaExceededResult(
                                filterContext.RequestContext,
                                string.Format(message, rateLimit, rateLimitPeriod),
                                QuotaExceededResponseCode,
                                requestId);

                            return;
                        }


把以上替换成

                        //check if limit is reached
                        if (rateLimit > 0 && throttleCounter.TotalRequests > rateLimit)
                        {
                            filterContext.HttpContext.Response.Redirect("/Error.html");
                            return;
                        }  

让其在超过次数时,跳转到项目根目录下的Error.html文件。

生成该类库,类库MvcThrottle.dll生成在类库的bin/Debug文件夹下。

在ASP.NET MVC 4 下创建一个项目。

在项目根目录下创建一个Library文件夹,把刚才的MvcThrottle.dll拷贝其中。

引用Library文件夹下的MvcThrottle.dll组件。

在App_Start文件夹中,修改FilterConfig类如下:

    public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            var throttleFilter = new ThrottlingFilter
            {
                Policy = new ThrottlePolicy(perSecond: 1, perMinute: 10, perHour: 60 * 10, perDay: 600 * 10)
                {
                    IpThrottling = true
                },
                Repository = new CacheRepository()
            };

            filters.Add(throttleFilter);
        }
    }

创建HomeController,编写如下:

    public class HomeController : Controller
    {

        public ActionResult Index()
        {
            return View();
        }

        [EnableThrottling(PerSecond = 2, PerMinute = 5, PerHour = 30, PerDay = 300)]
        public ActionResult Other()
        {
            return View();
        }

        [HttpPost]
        [EnableThrottling(PerSecond = 2, PerMinute = 5, PerHour = 30, PerDay = 300)]
        public ActionResult GetSth()
        {
            return Json(new {msg=true});
        }
    }


生成解决方案。

报错了!What Happened?

原来MvcThrottle是ASP.NET MVC 5下开发的。

有办法。重新打开MvcThrottle项目的类库,在引用中删除原来的System.Web.Mvc,重新引用本地ASP.NET MVC4版本,重新引用本地的System.Web.Mvc。

重新生成类库,重新拷贝到Library文件夹下,成功生成解决方案。

在Home/Index.cshtml视图中:

@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Index</h2>

<input type="button" id="btn" value="请求"/>

@section scripts
{
    <script type="text/javascript">
        $(function() {
            $(‘#btn‘).on("click", function() {
                $.post(‘@Url.Action("GetSth")‘,function(data) {
                    if (data.msg) {
                        alert("请求成功一次");
                    } else {
                        alert("请求次数过多");
                    }
                });
            });
        });
    </script>
}


当在单位时间间隔内超过规定次数,就弹出"请求次数过多"提示框。

在Home/Other.cshtml视图中:

@{
    ViewBag.Title = "Other";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Other</h2>

当在单位时间间隔内超过规定次数,就跳转到预定的Error.html页了。

时间: 2024-11-05 21:43:03

在ASP.NET MVC下限制同一个IP地址单位时间间隔内的请求次数的相关文章

在ASP.NET MVC下通过短信验证码注册

以前发短信使用过短信猫,现在,更多地是使用第三方API.大致过程是: → 用户在页面输入手机号码→ 用户点击"获取验证码"按钮,把手机号码发送给服务端,服务端产生几位数的随机码,并保存在某个地方(Session, Applicaiton, 数据库, 等等),调用第三方的API→ 第三方发送几位数的随机码至用户手机→ 用户在页面输入接收到的随机码→ 把随机码等发送给服务端,与服务端保存的随机码比较,如果一致,就通过,让注册 就按如下界面来说吧: 我们需要考虑的方面包括: ● 手机号码:判

ASP.NET MVC下的四种验证编程方式

原文:ASP.NET MVC下的四种验证编程方式 ASP.NET MVC采用Model绑定为目标Action生成了相应的参数列表,但是在真正执行目标Action方法之前,还需要对绑定的参数实施验证以确保其有效性,我们将针对参数的验证成为Model绑定.总地来说,我们可以采用4种不同的编程模式来进行针对绑定参数的验证. 目录 一.手工验证绑定的参数 二.使用ValidationAttribute特性 三.让数据类型实现IValidatableObject接口 四.让数据类型实现IDataError

ASP.NET MVC下的四种验证编程方式【转】

ASP.NET MVC采用Model绑定为目标Action生成了相应的参数列表,但是在真正执行目标Action方法之前,还需要对绑定的参数实施验证以确保其有效 性,我们将针对参数的验证成为Model绑定.总地来说,我们可以采用4种不同的编程模式来进行针对绑定参数的验证. 目录 一.手工验证绑定的参数 二.使用ValidationAttribute特性 三.让数据类型实现IValidatableObject接口 四.让数据类型实现IDataErrorInfo接口 一.手工验证绑定的参数 在 定义具

Asp.net mvc 中处理同一个session的并行请求的问题

首先来一个小的asp.net mvc 4的sample,代码如下: HomeController: using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.SessionState; namespace MvcApplication2.Controllers { public class HomeContr

ASP.NET MVC下的四种验证编程方式[续篇]

在<ASP.NET MVC下的四种验证编程方式>一文中我们介绍了ASP.NET MVC支持的四种服务端验证的编程方式("手工验证"."标注ValidationAttribute特性"."让数据类型实现IValidatableObject或者IDataErrorInfo"),那么在ASP.NET MVC框架内部是如何提供针对这四种不同编程方式的支持的呢?接下来我们就来聊聊这背后的故事. 一.ModelValidator与ModelVal

ASP.NET mvc下在Controller下action的跳转方式

在ASP.NET mvc下,action有多种挑战方式: return RedirectToAction("Index");//一个参数时在本Controller下 如果RedirectToAction(ActionName,ControllerName) //可以直接跳到别的Controller. return RedirectToRoute(new {controller="Home",action="Index"});//可跳到其他cont

在ASP.NET MVC下有关上传图片脏数据的解决方案

在"在ASP.NET MVC下实现单个图片上传, 客户端服务端双重限制图片大小和格式, 服务端裁剪图片"中,已经实现了在客户端和服务端限制图片大小和格式,以及在服务端裁剪图片.但还有一个重要的话题是需要面对的,那就是图片脏数据问题. 假设用户添加产品信息,并且上传了图片,可之后用户没有点击页面上的添加按钮,这就导致上传图片成为"脏数据",存在着却一直不会被使用.解决这个问题的大致思路是: ○ 在上传图片的时候,把图片保存到一个临时文件夹,或者叫缓存文件夹○ 当用户真

ASP.NET MVC下使用AngularJs语言(二):ng-click事件

程序用户交互,用户使用mouse点击,这是一个普通的功能. 在angularjs的铵钮点击命令是ng-click. 创建Angularjs的app使用前一篇<ASP.NET MVC下使用AngularJs语言(一):Hello your name>http://www.cnblogs.com/insus/p/8520555.html 的app. 创建Angularjs的controller: pilotApp.controller('ClickDemoCtrl', ['$http', '$lo

阿里云X-Forwarded-For 发现tomcat记录的日志全部来自于SLB转发的IP地址,不能获取到请求的真实IP。

1.背景:阿里云的SLB的负载均衡,在tomcat中获取不到真实IP,而是阿里的内网IP,SLB中俩台或者3台本身是局域网,这里是SLB原理,可以看看,没怎么看懂,呵呵,要细细读下. 2.需要开启tomcat的X-Forwarded-For,在tomcat/conf/server.xml中有一个如下的AccessLogValve 日志纪录功能,当配置中的pattern=common时,对应的日志是如下,无论正常请求和非法请求都会记录. <Valve className="org.apach