• api接口访问限制


    1.场景描述

         在日常开发接口的时候,尤其是restfull接口,肯定会考虑安全或者是做一些自定义的限制,用来界定并维护代码。那么,我们都会采用什么方法那?通常来讲,我们可以通过session的形式,以访问者的ip为键来记录用户对某接口访问的次数,并对其作出限制。在.net中还可以将session或者是MemoryCache来替换session来实现(另外也可以用第三方nosql:如redis、Mongodb等)。本文结合redis予以实现。

    2.实现分析

         通常来说,我们会可以在每一个需要被限制的接口使用redis来存储记录当前来访客户端访问的次数,这样,便可以实现我们想要的效果。但是,少啦可以,如果说,日后很多接口都需要限制该怎么办呐,我们该如何去整理并统筹规划呐?答案就是:可以采用Action过滤器标签的的形式,这样,我们只需封装这样可以限制访问的一个公用的过滤器标签,在需要被限制的地方加上标签,便可以得到我们想要的效果。废话不多说,直接上代码!!!

      1 public class ApiLimitFilter : ActionFilterAttribute
      2     {
      3         #region 可配参数
      4         //标识前缀(唯一)
      5         private string redisKeyPrefix;
      6         public string RedisKeyPrefix
      7         {
      8             get
      9             {
     10                 if (string.IsNullOrEmpty(redisKeyPrefix))
     11                 {
     12                     redisKeyPrefix = "Api_limit";
     13                 }
     14 
     15                 return redisKeyPrefix;
     16             }
     17             set { redisKeyPrefix = value; }
     18         }
     19         //显示时间长度
     20         private TimeSpan? timeSpan { get; set; }
     21         public TimeSpan? TimeSpan
     22         {
     23             get
     24             {
     25                 if (timeSpan == null)
     26                 {
     27                     timeSpan = System.TimeSpan.FromDays(1);
     28                 }
     29                 return timeSpan;
     30             }
     31             set { timeSpan = value; }
     32         }
     33         //显示次数
     34         private int limitCount;
     35         public int LimitCount
     36         {
     37             get
     38             {
     39                 if (limitCount <= 0)
     40                 {
     41                     limitCount = 5;
     42                 }
     43 
     44                 return limitCount;
     45             }
     46             set { limitCount = value; }
     47         }
     48         //提示语
     49         private string notify;
     50         public string Notify
     51         {
     52             get
     53             {
     54                 if (string.IsNullOrEmpty(notify))
     55                 {
     56                     notify = "请求受限";
     57                 }
     58 
     59                 return notify;
     60             }
     61             set { notify = value; }
     62         }
     63         #endregion
     64         #region 内部私用
     65         private string RedisKey
     66         {
     67             get { return string.Format("{0}_{1}", redisKeyPrefix, IpUtil.GetHostAddress()); }
     68         }
     69         private int currentCount = 0;
     70         #endregion
     71         #region Limit
     72         /// <summary>
     73         /// 限制过滤
     74         /// </summary>
     75         /// <param name="actionContext"></param>
     76         public override void OnActionExecuting(HttpActionContext actionContext)
     77         {
     78             //获取接口访问次数(redis封装的工具类/可切换自己想要的东西)
     79             currentCount = RedisCacheHelper.Instance.Get<int>(RedisKey);
     80             if (currentCount > LimitCount)
     81             {
     82                 var resultModel = new ResultModel(200, Notify);
     83                 actionContext.Response=actionContext.Request.CreateResponse(HttpStatusCode.OK, resultModel);
     84              
     85             }
     86             base.OnActionExecuting(actionContext);
     87         }
     88         /// <summary>
     89         /// 限制追记
     90         /// </summary>
     91         /// <param name="actionExecutedContext"></param>
     92         public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
     93         {
     94             currentCount++;
     95             //记住访问痕迹(redis封装的工具类/可切换自己想要的东西)
     96             RedisCacheHelper.Instance.Set(RedisKey, currentCount, TimeSpan);
     97             base.OnActionExecuted(actionExecutedContext);
     98         }
     99         #endregion
    100     }
    View Code
    力争写最通俗易懂的文章,不添加任何防腐剂~~~
  • 相关阅读:
    Ubuntu在命令行开启远程桌面
    Qt5编译项目出现GL/gl.h:No such file or directory错误
    硬盘录像机协议与技术汇总
    js判断IP字符串是否正确
    PHP获取原生POST数据
    hdu 5093 二分匹配
    hdu 4435 bfs+贪心
    hdu 4431 绝对值之和最小公式
    hdu 5073 推公式相邻质心转换
    hdu 3657 最小割(牛逼!!!!)总算理解了
  • 原文地址:https://www.cnblogs.com/diligent-lsh/p/10061258.html
Copyright © 2020-2023  润新知