AspNetCoreRateLimit有IP限流和客户端ID限制,这里只分享IP方式。
1.先安装AspNetCoreRateLimit
2.注入服务
#region Ip限流
//需要从加载配置文件appsettings.JSON
services.AddOptions();
//需要存储速率限制计算器和ip规则
services.AddMemoryCache();
// IpRateLimiting 配置
services.Configure<IpRateLimitOptions>(Configuration.GetSection("IpRateLimiting"));
services.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>();
services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();
services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
// 注册默认的 ProcessingStrategy
services.AddSingleton<IProcessingStrategy, AsyncKeyLockProcessingStrategy>();
//从appsettings.json中加载Ip规则
//services.Configure<IpRateLimitPolicies>(Configuration.GetSection("IpRateLimitPolicies"));
//注入计数器和规则存储
services.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>();
//services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();
//配置(解析器、计数器密钥生成器)
services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
#endregion
services.AddHttpContextAccessor();
services.AddControllers();
如果需要配置全局默认限制 可以把这个注释去掉: //services.Configure<IpRateLimitPolicies>(Configuration.GetSection("IpRateLimitPolicies"));
3.添加appsettings.json
配置
"IpRateLimiting": {
//false,则全局将应用限制,并且仅应用具有作为端点的规则*。例如,如果您设置每秒5次调用的限制,则对任何端点的任何HTTP调用都将计入该限制
//true, 则限制将应用于每个端点,如{HTTP_Verb}{PATH}。例如,如果您为*:/api/values客户端设置每秒5个呼叫的限制,
"EnableEndpointRateLimiting": false,
//false,拒绝的API调用不会添加到调用次数计数器上;如 客户端每秒发出3个请求并且您设置了每秒一个调用的限制,则每分钟或每天计数器等其他限制将仅记录第一个调用,即成功的API调用。如果您希望被拒绝的API调用计入其他时间的显示(分钟,小时等) //,则必须设置StackBlockedRequests为true。
"StackBlockedRequests": false,
//Kestrel 服务器背后是一个反向代理,如果你的代理服务器使用不同的页眉然后提取客户端IP X-Real-IP使用此选项来设置
"RealIpHeader": "X-Real-IP",
//取白名单的客户端ID。如果此标头中存在客户端ID并且与ClientWhitelist中指定的值匹配,则不应用速率限制。
"ClientIdHeader": "X-ClientId",
//限制状态码
"httpstatusCode": 429,
"QuotaExceededResponse": {
"Content": "{{ \"message\": \"你太快啦,请过一会再尝试.(●'◡'●)\", \"code\": 429,\"data \":\"\"}}",
"ContentType": "application/json"
},
IP白名单:支持Ip v4和v6
//"IpWhitelist": [ "127.0.0.1", "::1/10", "192.168.0.0/24" ],
端点白名单
//"EndpointWhitelist": [ "get:/api/license", "*:/api/status" ],
客户端白名单
//"ClientWhitelist": [ "dev-id-1", "dev-id-2" ],
//通用规则
"GeneralRules": [
{
//端点路径
"Endpoint": "*",
//时间段,格式:{数字}{单位};可使用单位:s, m, h, d
"Period": "1s",
//限制
"Limit": 3
}, //15分钟只能调用100次
{
"Endpoint": "*",
"Period": "15m",
"Limit": 100
}, //12H只能调用1000
{
"Endpoint": "*",
"Period": "12h",
"Limit": 1000
}, //7天只能调用10000次
{
"Endpoint": "*",
"Period": "7d",
"Limit": 10000
}
]
}//,
//"IpRateLimitPolicies": {
// "GlobalRules": [
// {
// "Rules": [
// // 对所有IP地址,在1秒内请求不超过10次
// {
// "Endpoint": "GET:api/TaskPublishes/GetPageTaskInfosAsync",
// "Period": "1s",
// "Limit": 5
// },
// // 对所有IP地址,在15分钟内请求不超过200次
// {
// "Endpoint": "*",
// "Period": "15m",
// "Limit": 200
// },
// // 对所有IP地址,在12小时内请求不超过500次
// {
// "Endpoint": "*",
// "Period": "12h",
// "Limit": 500
// }
// ]
// }
// ]
//}
IpRateLimitPolicies和IpRateLimiting
使用一个就行 ,如果全局通用限制,使用IpRateLimitPolicies
就行了,如果你只需要限制特定的路径,只需要配置IpRateLimiting
一个就行,如果IpRateLimiting和IpRateLimitPolicies
同时使用,会有冲突。也是导致不起作用的原因。
下面给出特定路径配置:
"IpRateLimiting": {
//false,则全局将应用限制,并且仅应用具有作为端点的规则*。例如,如果您设置每秒5次调用的限制,则对任何端点的任何HTTP调用都将计入该限制
//true, 则限制将应用于每个端点,如{HTTP_Verb}{PATH}。例如,如果您为*:/api/values客户端设置每秒5个呼叫的限制,
"EnableEndpointRateLimiting": true,
//false,拒绝的API调用不会添加到调用次数计数器上;如 客户端每秒发出3个请求并且您设置了每秒一个调用的限制,则每分钟或每天计数器等其他限制将仅记录第一个调用,即成功的API调用。如果您希望被拒绝的API调用计入其他时间的显示(分钟,小时等) //,则必须设置StackBlockedRequests为true。
"StackBlockedRequests": false,
//Kestrel 服务器背后是一个反向代理,如果你的代理服务器使用不同的页眉然后提取客户端IP X-Real-IP使用此选项来设置
"RealIpHeader": "X-Real-IP",
//取白名单的客户端ID。如果此标头中存在客户端ID并且与ClientWhitelist中指定的值匹配,则不应用速率限制。
"ClientIdHeader": "X-ClientId",
//限制状态码
"httpstatusCode": 429,
"QuotaExceededResponse": {
"Content": "{{ \"message\": \"你太快啦,请过一会再尝试.(●'◡'●)\", \"code\": 429,\"data \":\"\"}}",
"ContentType": "application/json"
},
IP白名单:支持Ip v4和v6
//"IpWhitelist": [ "127.0.0.1", "::1/10", "192.168.0.0/24" ],
端点白名单
//"EndpointWhitelist": [ "get:/api/license", "*:/api/status" ],
客户端白名单
//"ClientWhitelist": [ "dev-id-1", "dev-id-2" ],
//通用规则
"GeneralRules": [
{
//端点路径
"Endpoint": "*:/api/Task/GetTaskInfosAsync",
//时间段,格式:{数字}{单位};可使用单位:s, m, h, d
"Period": "1s",
//限制
"Limit": 3
}, //15分钟只能调用100次
{
"Endpoint": "*:/api/TaskPublishes/GetTaskInfosAsync",
"Period": "15m",
"Limit": 100
}, //12H只能调用1000
{
"Endpoint": "*:/api/TaskPublishes/GetTaskInfosAsync",
"Period": "12h",
"Limit": 1000
}, //7天只能调用10000次
{
"Endpoint": "*:/api/TaskPublishes/GetTaskInfosAsync",
"Period": "7d",
"Limit": 10000
}
]
}