api接口訪問限制

1.場景描述

     在平常開發接口的時候,尤爲是restfull接口,確定會考慮安全或者是作一些自定義的限制,用來界定並維護代碼。那麼,咱們都會採用什麼方法那?一般來說,咱們能夠經過session的形式,以訪問者的ip爲鍵來記錄用戶對某接口訪問的次數,並對其做出限制。在.net中還能夠將session或者是MemoryCache來替換session來實現(另外也能夠用第三方nosql:如redis、Mongodb等)。本文結合redis予以實現。redis

2.實現分析

     一般來講,咱們會能夠在每個須要被限制的接口使用redis來存儲記錄當前來訪客戶端訪問的次數,這樣,即可以實現咱們想要的效果。可是,少啦能夠,若是說,往後不少接口都須要限制該怎麼辦吶,咱們該如何去整理並統籌規劃吶?答案就是:能夠採用Action過濾器標籤的的形式,這樣,咱們只需封裝這樣能夠限制訪問的一個公用的過濾器標籤,在須要被限制的地方加上標籤,即可以獲得咱們想要的效果。廢話很少說,直接上代碼!!!sql

  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
相關文章
相關標籤/搜索