首页 > 其他分享 >简单的限流过滤器

简单的限流过滤器

时间:2024-06-12 17:43:23浏览次数:14  
标签:string Cache clientId 限流 userHostAddress 简单 过滤器 public

API接口都是提供给第三方服务/客户端调用,所有请求地址以及请求参数都是暴露给用户的。

每次请求一个HTTP请求,用户都可以通过F12,或者抓包工具看到请求的URL链接,然后copy出来。这样是非常不安全的,有人可能会恶意的刷我们的接口,那这时该怎么办呢?

增加一个全局过滤器 获取客户端的IP  限制固定时间内的访问次数即可

第一步:创建全局过滤器 RateLimitFilter

 public class RateLimitFilter : ActionFilterAttribute
    {
        private const int MaxRequests = 30; //1分钟访问最大频率
        private bool StartUp = true; //是否启用
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            if (StartUp)
            {
                base.OnActionExecuting(context);
                string clientId = GetIP();
                if (GetCache(clientId) == null)
                {
                    SetCacheRelativeTime(clientId, 1, 60);
                }
                else
                {
                    var cs = int.Parse(GetCache(clientId).ToString());
                    SetCacheRelativeTime(clientId, cs += 1, 60);
                }
                //var x = int.Parse(GetCache(clientId).ToString());
                if (int.Parse(GetCache(clientId).ToString()) > MaxRequests)
                {
                    //返回值规范不统一
                    context.Result = new ContentResult { Content = "<script type='text/javascript'>alert('" + clientId + "  访问过于频繁,请稍等片刻!');</script><h1 style='text-align: center; color: red;'>" + clientId + "  访问过于频繁,请稍等片刻!<h1>" };

                    //返回值规范统一   前端有错误提示
                    //context.Result = new JsonResult()
                    //{
                    //    Data = new { Result = false, status = false, suc = false, message = "" + clientId + "  访问过于频繁,请稍等片刻!" },
                    //    JsonRequestBehavior = JsonRequestBehavior.AllowGet
                    //};
                }
            } 
        }


        /// <summary>
        /// 获取客户端IP地址
        /// </summary>
        /// <returns>若失败则返回回送地址</returns>
        public static string GetIP()
        {
            //如果客户端使用了代理服务器,则利用HTTP_X_FORWARDED_FOR找到客户端IP地址
            string userHostAddress = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
            if (!string.IsNullOrEmpty(userHostAddress))
            {
                userHostAddress = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString().Split(',')[0].Trim();
            }
            //否则直接读取REMOTE_ADDR获取客户端IP地址
            if (string.IsNullOrEmpty(userHostAddress))
            {
                userHostAddress = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
            }
            //前两者均失败,则利用Request.UserHostAddress属性获取IP地址,但此时无法确定该IP是客户端IP还是代理IP
            if (string.IsNullOrEmpty(userHostAddress))
            {
                userHostAddress = HttpContext.Current.Request.UserHostAddress;
            }
            //最后判断获取是否成功,并检查IP地址的格式(检查其格式非常重要)
            if (!string.IsNullOrEmpty(userHostAddress) && IsIP(userHostAddress))
            {
                return userHostAddress;
            }
            return "127.0.0.1";
        }

        /// <summary>
        /// 检查IP地址格式
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        public static bool IsIP(string ip)
        {
            return System.Text.RegularExpressions.Regex.IsMatch(ip, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$");
        }

        #region  设置相对过期时间Cache值(即:访问激活后不过期)
        /// <summary>        
        /// 设置相对过期时间Cache值(即:访问激活后不过期)
        /// </summary>        
        /// <param name="objectkey"></param>        
        /// <param name="objObject"></param>        
        /// <param name="timeSpan">超过多少时间不调用就失效,单位是秒</param>        

        public static void SetCacheRelativeTime(string objectkey, object objObject, int timeSpan)
        {
            System.Web.Caching.Cache objCache = HttpRuntime.Cache;
            objCache.Insert(objectkey, objObject, null, DateTime.MaxValue, TimeSpan.FromSeconds(timeSpan));
        }
        #endregion

        #region  获取当前应用程序指定CacheKey的Cache值
        /// <summary>
        /// 获取当前应用程序指定CacheKey的Cache值
        /// </summary>
        /// <param name="CacheKey"></param>
        /// <returns></returns>y
        public static object GetCache(string CacheKey)
        {
            try
            {
                System.Web.Caching.Cache objCache = HttpRuntime.Cache;
                Object value = objCache[CacheKey];
                if (value != null)
                {
                    return value;
                }
                else
                {
                    return null;
                }
            }
            catch (Exception)
            {
                return null;
            }

        }
        #endregion
    }

 

第二步:FilterConfig类并注册你的全局过滤器

 public class FilterConfig
 {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new RateLimitFilter()); // 过滤器
        }
 }

第三步:Global.asax 文件中注册全局过滤器

protected void Application_Start()
{
            AreaRegistration.RegisterAllAreas();
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            UnityConfig.RegisterComponents();

            // 注册全局过滤器
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);

}

 

标签:string,Cache,clientId,限流,userHostAddress,简单,过滤器,public
From: https://www.cnblogs.com/zj19940610/p/18244414

相关文章

  • JSON 和对象的互转(fastjson2 的简单使用)
    fastjson2的简单使用导包随便挑个版本<dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>2.0.25</version></dependency>使用单个对象Stringstr=JSON.toJSONString......
  • [SWPUCTF 2021 新生赛]简简单单的逻辑
    查看源代码,大概意思就是已知result反推flagflag='xxxxxxxxxxxxxxxxxx'list=[47,138,127,57,117,188,51,143,17,84,42,135,76,105,28,169,25]result=''foriinrange(len(list)):key=(list[i]>>4)+((list[i]&0xf)<<......
  • [鹏城杯 2022]简单包含
    highlight_file(__FILE__);include($_POST["flag"]);//flagin/var/www/html/flag.php;题目只给了一个include以及flag的路径,尝试使用伪协议读取flag.phpflag=php://filter/convert.base64-encode/resource=flag.php直接读取发现存在waf,猜想肯定是过滤了flag字符串,这里我原......
  • [数据分析与可视化] 基于Python绘制简单动图
    动画是一种高效的可视化工具,能够提升用户的吸引力和视觉体验,有助于以富有意义的方式呈现数据可视化。本文的主要介绍在Python中两种简单制作动图的方法。其中一种方法是使用matplotlib的Animations模块绘制动图,另一种方法是基于Pillow生成GIF动图。python学习资料已打包好,需......
  • 简单聊聊计算机之中的时间
    在工作中,程序员难免和时间打交道。那么时间背后的原理是什么呢?为什么会有闰年、闰秒呢?‍昼夜的由来我们先简单聊聊昼夜是怎么来的。如果你高中时学过地理,那么应该会知道为什么有昼夜和四季,可以暂时略过本小节首先,地球是一个球体(确切的说,是一个椭圆的球体)太阳也是一个球体,只......
  • 简单易懂的JSON框架
      分享一个由本人编写的JSON框架。  JSON反序列化使用递归方式来解析JSON字符串,不使用任何第三方JAR包,只使用JAVA的反射来创建对象(必须要有无参构造器),赋值,编写反射缓存来提升性能。支持复杂的泛型类型,数组类型等所有类型。(不支持高版本JDK1.8以上的日期类型,如LocalDate,LocalD......
  • stable diffusion安装简单记录
    参考bilibili的教程就好。https://www.bilibili.com/video/BV1R8411x78T/?share_source=copy_web&vd_source=6ff698460da12b7358d0dd9391c0b4b4 注意问题1、需要有外网访问~~up主提供的文档,这个文档中涉及到huggingface地址的访问,这是个外网地址(安全上网方式自行查询)。2、py......
  • NumPy 简单算术:加减乘除及其他运算
    简单算术你可以直接在NumPy数组之间使用算术运算符+-*/,但本节讨论了一个扩展,其中我们有函数可以接受任何类似数组的对象,如列表、元组等,并根据条件执行算术运算。条件算术:意味着我们可以定义算术运算应该发生的条件。所有讨论过的算术函数都接受一个where参数,我们可以在......
  • [20240529]简单探究FREE LISTS列表.txt
    [20240529]简单探究FREELISTS列表.txt--//简单探究shraedpool的FREELISTS列表.1.环境:SYS@test>@ver1PORT_STRING         VERSION   BANNER                                                       ......
  • [20240601]简单探究free list chunk size的分布.txt
    [20240601]简单探究freelistchunksize的分布.txt--//前几天探究探究freelist,无意中发现12c版本freelistchunksize的发生了变化.单独另外写一篇blog.--//我开始分析以为脚本执行有问题,仔细查看12c版本freelistchunksize分布发生了变化.--//我找了以前的11g下的转储,发......