api接口访问限制
1.場(chǎng)景描述
? ? ?在日常開發(fā)接口的時(shí)候,尤其是restfull接口,肯定會(huì)考慮安全或者是做一些自定義的限制,用來界定并維護(hù)代碼。那么,我們都會(huì)采用什么方法那?通常來講,我們可以通過session的形式,以訪問者的ip為鍵來記錄用戶對(duì)某接口訪問的次數(shù),并對(duì)其作出限制。在.net中還可以將session或者是MemoryCache來替換session來實(shí)現(xiàn)(另外也可以用第三方nosql:如redis、Mongodb等)。本文結(jié)合redis予以實(shí)現(xiàn)。
2.實(shí)現(xiàn)分析
? ? ?通常來說,我們會(huì)可以在每一個(gè)需要被限制的接口使用redis來存儲(chǔ)記錄當(dāng)前來訪客戶端訪問的次數(shù),這樣,便可以實(shí)現(xiàn)我們想要的效果。但是,少啦可以,如果說,日后很多接口都需要限制該怎么辦吶,我們?cè)撊绾稳フ聿⒔y(tǒng)籌規(guī)劃吶?答案就是:可以采用Action過濾器標(biāo)簽的的形式,這樣,我們只需封裝這樣可以限制訪問的一個(gè)公用的過濾器標(biāo)簽,在需要被限制的地方加上標(biāo)簽,便可以得到我們想要的效果。廢話不多說,直接上代碼!!!
1 public class ApiLimitFilter : ActionFilterAttribute 2 { 3 #region 可配參數(shù) 4 //標(biāo)識(shí)前綴(唯一) 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 //顯示時(shí)間長(zhǎng)度 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 //顯示次數(shù) 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 = "請(qǐng)求受限"; 57 } 58 59 return notify; 60 } 61 set { notify = value; } 62 } 63 #endregion 64 #region 內(nèi)部私用 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 //獲取接口訪問次數(shù)(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?
轉(zhuǎn)載于:https://www.cnblogs.com/diligent-lsh/p/10061258.html
總結(jié)
- 上一篇: buttfly主题魔改
- 下一篇: AWS EC2使用