经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » 编程经验 » 查看文章
简单的限流过滤器
来源:cnblogs  作者:风中起舞  时间:2024/6/12 17:43:24  对本文有异议

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

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

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

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

  1. public class RateLimitFilter : ActionFilterAttribute
  2. {
  3. private const int MaxRequests = 30; //1分钟访问最大频率
  4. private bool StartUp = true; //是否启用
  5. public override void OnActionExecuting(ActionExecutingContext context)
  6. {
  7. if (StartUp)
  8. {
  9. base.OnActionExecuting(context);
  10. string clientId = GetIP();
  11. if (GetCache(clientId) == null)
  12. {
  13. SetCacheRelativeTime(clientId, 1, 60);
  14. }
  15. else
  16. {
  17. var cs = int.Parse(GetCache(clientId).ToString());
  18. SetCacheRelativeTime(clientId, cs += 1, 60);
  19. }
  20. //var x = int.Parse(GetCache(clientId).ToString());
  21. if (int.Parse(GetCache(clientId).ToString()) > MaxRequests)
  22. {
  23. //返回值规范不统一
  24. context.Result = new ContentResult { Content = "<script type='text/javascript'>alert('" + clientId + " 访问过于频繁,请稍等片刻!');</script><h1 style='text-align: center; color: red;'>" + clientId + " 访问过于频繁,请稍等片刻!<h1>" };
  25. //返回值规范统一 前端有错误提示
  26. //context.Result = new JsonResult()
  27. //{
  28. // Data = new { Result = false, status = false, suc = false, message = "" + clientId + " 访问过于频繁,请稍等片刻!" },
  29. // JsonRequestBehavior = JsonRequestBehavior.AllowGet
  30. //};
  31. }
  32. }
  33. }
  34. /// <summary>
  35. /// 获取客户端IP地址
  36. /// </summary>
  37. /// <returns>若失败则返回回送地址</returns>
  38. public static string GetIP()
  39. {
  40. //如果客户端使用了代理服务器,则利用HTTP_X_FORWARDED_FOR找到客户端IP地址
  41. string userHostAddress = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
  42. if (!string.IsNullOrEmpty(userHostAddress))
  43. {
  44. userHostAddress = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString().Split(',')[0].Trim();
  45. }
  46. //否则直接读取REMOTE_ADDR获取客户端IP地址
  47. if (string.IsNullOrEmpty(userHostAddress))
  48. {
  49. userHostAddress = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
  50. }
  51. //前两者均失败,则利用Request.UserHostAddress属性获取IP地址,但此时无法确定该IP是客户端IP还是代理IP
  52. if (string.IsNullOrEmpty(userHostAddress))
  53. {
  54. userHostAddress = HttpContext.Current.Request.UserHostAddress;
  55. }
  56. //最后判断获取是否成功,并检查IP地址的格式(检查其格式非常重要)
  57. if (!string.IsNullOrEmpty(userHostAddress) && IsIP(userHostAddress))
  58. {
  59. return userHostAddress;
  60. }
  61. return "127.0.0.1";
  62. }
  63. /// <summary>
  64. /// 检查IP地址格式
  65. /// </summary>
  66. /// <param name="ip"></param>
  67. /// <returns></returns>
  68. public static bool IsIP(string ip)
  69. {
  70. 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?)$");
  71. }
  72. #region 设置相对过期时间Cache值(即:访问激活后不过期)
  73. /// <summary>
  74. /// 设置相对过期时间Cache值(即:访问激活后不过期)
  75. /// </summary>
  76. /// <param name="objectkey"></param>
  77. /// <param name="objObject"></param>
  78. /// <param name="timeSpan">超过多少时间不调用就失效,单位是秒</param>
  79.  
  80. public static void SetCacheRelativeTime(string objectkey, object objObject, int timeSpan)
  81. {
  82. System.Web.Caching.Cache objCache = HttpRuntime.Cache;
  83. objCache.Insert(objectkey, objObject, null, DateTime.MaxValue, TimeSpan.FromSeconds(timeSpan));
  84. }
  85. #endregion
  86.  
  87. #region 获取当前应用程序指定CacheKey的Cache值
  88. /// <summary>
  89. /// 获取当前应用程序指定CacheKey的Cache值
  90. /// </summary>
  91. /// <param name="CacheKey"></param>
  92. /// <returns></returns>y
  93. public static object GetCache(string CacheKey)
  94. {
  95. try
  96. {
  97. System.Web.Caching.Cache objCache = HttpRuntime.Cache;
  98. Object value = objCache[CacheKey];
  99. if (value != null)
  100. {
  101. return value;
  102. }
  103. else
  104. {
  105. return null;
  106. }
  107. }
  108. catch (Exception)
  109. {
  110. return null;
  111. }
  112. }
  113. #endregion
  114. }

 

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

  1. public class FilterConfig
  2. {
  3. public static void RegisterGlobalFilters(GlobalFilterCollection filters)
  4. {
  5. filters.Add(new RateLimitFilter()); // 过滤器
  6. }
  7. }

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

  1. protected void Application_Start()
  2. {
  3. AreaRegistration.RegisterAllAreas();
  4. RouteConfig.RegisterRoutes(RouteTable.Routes);
  5. BundleConfig.RegisterBundles(BundleTable.Bundles);
  6. UnityConfig.RegisterComponents();
  7. // 注册全局过滤器
  8. FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
  9. }

 

原文链接:https://www.cnblogs.com/zj19940610/p/18244414

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号