web api 限制单个IP在一定时间内访问次数
ps:下面实例是每隔30秒访问次数不超过3次
1、Filter:
using Infrastructure.Log;
using Infrastructure.Web;
using Lemon.Stats.Model;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http.Controllers;
using System.Web.Http.Filters; namespace Lemon.Stats.Apis
{
/// <summary>
/// 限制单个IP短时间内访问次数
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
public class IPActionFilterAttribute : ActionFilterAttribute
{
/// <summary>
/// 限制单个IP短时间内访问次数
/// </summary>
/// <param name="actionContext"></param>
public override void OnActionExecuting(HttpActionContext actionContext)
{
string ip = HttpHelper.GetClientIp(actionContext.Request);
//var isValid = IPCacheHelper.CheckIsAble(ip);
IPCacheInfoModel ipModel = IPCacheHelper.GetIPLimitInfo(ip);
if (!ipModel.IsVisit)
{
Logger.Warn(string.Format("IP【{0}】被限制了【{1}】次数",ipModel.IP,ipModel.Limit));
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.BadRequest, "系统正忙,请稍微再试。");
return;
}
base.OnActionExecuting(actionContext);
} }
}
2、IPCacheHelper:
using Lemon.Stats.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Lemon.Stats.Apis
{
/// <summary>
/// 限制单个IP访问次数
/// </summary>
public class IPCacheHelper
{
/// <summary>
/// IP缓存集合
/// </summary>
private static List<IPCacheInfoModel> dataList = new List<IPCacheInfoModel>(); private static object lockObj = new object(); /// <summary>
/// 一段时间内,最大请求次数,必须大于等于1
///</summary>
private static int maxTimes = ; /// <summary>
/// 一段时间长度(单位秒),必须大于等于1
/// </summary>
private static int partSecond = ; /// <summary>
/// 请求被拒绝是否加入请求次数
/// </summary>
private static bool isFailAddIn = false; static IPCacheHelper()
{ } /// <summary>
/// 设置时间,默认maxTimes=3, partSecond=30
/// </summary>
/// <param name="_maxTimes">最大请求次数</param>
/// <param name="_partSecond">请求单位时间</param>
public static void SetTime(int _maxTimes, int _partSecond)
{
maxTimes = _maxTimes;
partSecond = _partSecond;
} /// <summary>
/// 检测一段时间内,IP的请求次数是否可以继续请求和使用
/// </summary>
/// <param name="ip">ip</param>
/// <returns></returns>
public static bool CheckIsAble(string ip)
{
lock (lockObj)
{
var item = dataList.Find(p => p.IP == ip);
if (item == null)
{
item = new IPCacheInfoModel();
item.IP = ip;
item.ReqTime.Add(DateTime.Now);
dataList.Add(item);
return true;
}
else
{
if (item.ReqTime.Count > maxTimes)
{
item.ReqTime.RemoveAt();
}
var nowTime = DateTime.Now;
if (isFailAddIn)
{
#region 请求被拒绝也需要加入当次请求
item.ReqTime.Add(nowTime);
if (item.ReqTime.Count >= maxTimes)
{
if (item.ReqTime[].AddSeconds(partSecond) > nowTime)
{
return false;
}
else
{
return true;
}
}
else
{
return true;
}
#endregion
}
else
{
#region 请求被拒绝就不需要加入当次请求了
if (item.ReqTime.Count >= maxTimes)
{
if (item.ReqTime[].AddSeconds(partSecond) > nowTime)
{
return false;
}
else
{
item.ReqTime.Add(nowTime);
return true;
}
}
else
{
item.ReqTime.Add(nowTime);
return true;
}
#endregion
}
}
}
} /// <summary>
/// 检测一段时间内,IP的请求次数是否可以继续请求和使用
/// </summary>
/// <param name="ip">ip</param>
/// <returns></returns>
public static IPCacheInfoModel GetIPLimitInfo(string ip)
{
lock (lockObj)
{
var item = dataList.Find(p => p.IP == ip);
if (item == null) //IP开始访问
{
item = new IPCacheInfoModel();
item.IP = ip;
item.ReqTime.Add(DateTime.Now);
dataList.Add(item);
item.IsVisit = true; //可以继续访问 return item;
}
else
{
if (item.ReqTime.Count > maxTimes)
{
item.ReqTime.RemoveAt();
}
var nowTime = DateTime.Now;
if (isFailAddIn)
{
#region 请求被拒绝也需要加入当次请求
item.ReqTime.Add(nowTime); if (item.ReqTime.Count >= maxTimes)
{
if (item.ReqTime[].AddSeconds(partSecond) > nowTime)
{
item.Limit++; //限制次数+1
item.IsVisit = false;//不能继续访问
return item;
}
else
{
item.IsVisit = true; //可以继续访问
return item; //单个IP30秒内 没有多次访问
}
}
else
{
item.IsVisit = true; //可以继续访问
return item; //单个IP访问次数没有达到max次数
}
#endregion
}
else
{
#region 请求被拒绝就不需要加入当次请求了
if (item.ReqTime.Count >= maxTimes)
{
if (item.ReqTime[].AddSeconds(partSecond) > nowTime)
{
item.Limit++; //限制次数+1
item.IsVisit = false;//不能继续访问 return item;
}
else
{
item.ReqTime.Add(nowTime); item.IsVisit = true; //可以继续访问
return item;
}
}
else
{
item.ReqTime.Add(nowTime);
item.IsVisit = true; //可以继续访问 return item;
}
#endregion
}
}
}
}
}
}
3、IPCacheInfoModel:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Lemon.Stats.Model
{
public class IPCacheInfoModel
{
/// <summary>
/// IP
/// </summary>
public string IP { get; set; } /// <summary>
/// 限制次数
/// </summary>
public int Limit { get; set; } /// <summary>
/// 是否可以访问
/// </summary>
public bool IsVisit { get; set; } /// <summary>
/// 访问时间
/// </summary>
private List<DateTime> reqTime = new List<DateTime>(); /// <summary>
/// 访问时间
/// </summary>
public List<DateTime> ReqTime
{
get { return this.reqTime; }
set { this.reqTime = value; }
}
}
}
4、Action:
/// <summary>
/// IP,PV(VV),UV,注册用户点击量统计
/// 先执行IPActionFilter过滤器,再执行ChannelActionFilter过滤器
/// 先执行后面的过滤器,再执行前面的过滤器,执行方式倒序执行顺序
/// </summary>
[ChannelActionFilter, IPActionFilter, RoutePrefix("Stats")]
public class StatsController : ApiController
{ /// <summary>
/// 每次页面点击都统计数据,直接由客户端调用
/// Header中加入SecretKey,AppKey,UniqueKey
/// </summary>
/// <returns></returns>
[HttpGet, Route("")]
public async Task Get()
{ }
}
web api 限制单个IP在一定时间内访问次数的更多相关文章
- Web Api 2(Cors)Ajax跨域访问
支持Ajax跨域访问ASP.NET Web Api 2(Cors)的简单示例教程演示 随着深入使用ASP.NET Web Api,我们可能会在项目中考虑将前端的业务分得更细.比如前端项目使用Ang ...
- 分ip统计网站访问次数
package web.listener; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; ...
- Filter和Listener的应用——分IP统计网站访问次数
一:分析 统计工作需要在所有资源执行前进行,所以需要放在filter中 这个拦截器仅仅进行统计工作,不进行拦截,所以请求必须继续传递下去 用Map<String,integer>来保存数据 ...
- ASP.NET Web API使用示例
原文地址:https://blog.csdn.net/chinacsharper/article/details/21333311 上篇博客讲解rest服务开发时,曾经提到过asp.net mvc中的 ...
- asp.net mvc 5 web api 关于Requested resource does not support options 问题
1.用visual studio 2015 建立一个 web api 应用程序.记住这是一个 web api 应用. 2.新建一个web api . 3.用C#访问,代码如下:[没有问题,返回正确] ...
- Web API应用架构在Winform混合框架中的应用(4)--利用代码生成工具快速开发整套应用
前面几篇介绍了Web API的基础信息,以及如何基于混合框架的方式在WInform界面里面整合了Web API的接入方式,虽然我们看似调用过程比较复杂,但是基于整个框架的支持和考虑,我们提供了代码生成 ...
- ASP.NET MVC Web API使用示例
上篇博客讲解rest服务开发时,曾经提到过asp.net mvc中的rest api,由于篇幅原因,没有在上篇博客中进行讲解,这里专门拿出来进行讨论.还是一样引用上次的案例,用asp.net mvc提 ...
- Xamarin.Android 调用Web Api(通过ListView展示远程获取的数据)
xamarin.android如何调用sqlserver 数据库呢(或者其他的),很多新手都会有这个疑问.xamarin.android调用远程数据主要有两种方式: 在Android中保存数据或调用数 ...
- 前端使用AngularJS的$resource,后端ASP.NET Web API,实现增删改查
AngularJS中的$resource服务相比$http服务更适合与RESTful服务进行交互.本篇后端使用ASP.NET Web API, 前端使用$resource,实现增删改查. 本系列包括: ...
随机推荐
- There is an internal error in the React performance measurement code.Did not expect componentDidMount timer to start while render timer is still in progress for another instance
一.There is an internal error in the React performance measurement code.Did not expect componentDidMo ...
- 【Android】Activity生命周期(亲测)
测试手机:Nexus 5 系统:4.4 一.测试 测试代码: package com.example.androidalarm; import android.app.Activity; impo ...
- 网络拥塞控制与NS2仿真
准备工作: 1. 安装virtual box 虚拟机,并安装虚拟机增强功能,并配制共享文件夹. 共享文件夹自动挂载后的路径为/media/sf_xxx文件夹,xxx为所起的文件名. 解决virtual ...
- SNF开发平台WinForm之八-自动升级程序部署使用说明-SNF快速开发平台3.3-Spring.Net.Framework
9.1运行效果: 9.2开发实现: 1.首先配置服务器端,把“SNFAutoUpdate2.0\服务器端部署“目录按网站程序进行发布到IIS服务器上. 2.粘贴语句,生成程序 需要调用的应用程序的Lo ...
- MyBatis知多少(12)私有数据库
如果你从事软件开发工作有了一段时间的话,那么肯定听过关于“自己动手还是花钱购买” 的争论.该争论是说,针对一个业务问题,我们是应该自己动手构建自己的解决方案呢,还是应 该花钱购买一个声称已经解决了此问 ...
- mysql提示:Illegal mix of collations for operation ‘UNION’
http://www.111cn.net/database/mysql/56096.htm show variables like "%char%"; show variables ...
- Android debug时一直处于waiting for debugger解决办法
问题:android 调试卡在:Waiting for Debugger - Application XXX is waiting for the debugger to Attach" 解 ...
- chrome 插件 vimium 像操作vim一样的操作浏览器
感谢潘德龙同学推荐的插件非常好用整理出来一些常用快捷键记下,顺便分享! x 关闭当前页 GW 跳出浏览器 J 展示左边页签 K展示右边页签 j向下滚动 k向上滚动 /搜索 ?打开帮助 r 刷新当前页 ...
- [OpenCV] Identify and Track Specific Object
Abstract—Augmented Reality (AR) has become increasingly popular in recent years and it has a widespr ...
- Ladda – 把加载提示效果集成到按钮中,提升用户体验
Ladda 是一组集成了加载提示的按钮,以弥合行动和反馈之间的时间间隔,提供更好的功能使用体验.主要用于在用户点击提交之后,向用户提供即时的反馈,让他们知道浏览器正在处用户提交的任务. 您可能感兴趣的 ...