限制用户对服务的请求次数(Web,WebApi)
通过对缓存的操作进行请求次数的限制
环境:.NET 6.0
准备
- nuget包:AspNetCoreRateLimit
- github:https://github.com/stefanprodan/AspNetCoreRateLimit
- nuget包:Swashbuckle.AspNetCore
- github:https://github.com/domaindrivendev/Swashbuckle.AspNetCore
- 创建一个webapi项目(可选集成Swagger)
开始
创建全局限制配置文件
Limit.json(文件名字可以为其的)
{
// IP限流配置
"IpRateLimiting": {
// 例如:设置每分钟5次访问限流
// 当False时:每个接口都加入计数,不管你访问哪个接口,只要在一分钟内累计够5次,将禁止访问。
// 当True 时:当一分钟请求了5次GetData接口,则该接口将在时间段内禁止访问,但是还可以访问PostData()5次,总得来说是每个接口都有5次在这一分钟,互不干扰。
"EnableEndpointRateLimiting": true,
// 如果StackBlockedRequests设置为false,拒绝的API调用不会添加到调用次数计数器上。比如:如果客户端每秒发出3个请求并且您设置了每秒一个调用的限制,
// 则每分钟或每天计数器等其他限制将仅记录第一个调用,即成功的API调用。如果您希望被拒绝的API调用计入其他时间的显示(分钟,小时等),则必须设置
"StackBlockedRequests": false,
// 在RealIpHeader使用时,你的Kestrel服务器背后是一个反向代理,如果你的代理服务器使用不同的页眉然后提取客户端IP X-Real-IP使用此选项来设置它。
"RealIpHeader": "X-Real-IP",
// 将ClientIdHeader被用于提取白名单的客户端ID。如果此标头中存在客户端ID并且与ClientWhitelist中指定的值匹配,则不应用速率限制。
"ClientIdHeader": "X-ClientId",
// IP白名单:支持Ipv4和Ipv6
"IpWhitelist": [],
// 端点白名单
"EndpointWhitelist": [],
// 客户端白名单
"ClientWhitelist": [],
"QuotaExceededResponse": {
"Content": "{{\"code\":429,\"type\":\"error\",\"message\":\"访问过于频繁,请稍后重试!\",\"result\":null,\"extras\":null}}",
"ContentType": "application/json",
"StatusCode": 429
},
// 返回状态码
"HttpStatusCode": 429,
// API规则,结尾一定要带*
"GeneralRules": [
// 1秒钟只能调用1次
{
"Endpoint": "*",
"Period": "1s",
"Limit": 10
},
// 1分钟只能调用100次
{
"Endpoint": "*",
"Period": "1m",
"Limit": 1000
},
// 1小时只能调用1000
{
"Endpoint": "*",
"Period": "1h",
"Limit": 10000
},
// 1天只能调用10000次
{
"Endpoint": "*",
"Period": "1d",
"Limit": 1000000
}
]
},
"IpRateLimitPolicies": {
"IpRules": [
{
"Ip": "XXX.XXX.XXX.XXX",
"Rules": [
{
"Endpoint": "*",
"Period": "1s",
"Limit": 10
},
{
"Endpoint": "*",
"Period": "1m",
"Limit": 1000
}
]
}
]
},
// 客户端限流配置
"ClientRateLimiting": {
"EnableEndpointRateLimiting": true,
"ClientIdHeader": "X-ClientId",
"EndpointWhitelist": [],
"ClientWhitelist": [],
"QuotaExceededResponse": {
"Content": "{{\"code\":429,\"type\":\"error\",\"message\":\"访问人数过多,请稍后重试!\",\"result\":null,\"extras\":null}}",
"ContentType": "application/json",
"StatusCode": 429
},
"HttpStatusCode": 429,
"GeneralRules": [
{
"Endpoint": "*",
"Period": "1s",
"Limit": 10
},
{
"Endpoint": "*",
"Period": "1m",
"Limit": 1000
}
]
},
"ClientRateLimitPolicies": {
"ClientRules": [
{
"ClientId": "xxx-xxx",
"Rules": [
{
"Endpoint": "*",
"Period": "1s",
"Limit": 10
},
{
"Endpoint": "*",
"Period": "1m",
"Limit": 1000
}
]
}
]
}
}
文件属性设置
修改Program.cs
using AspNetCoreRateLimit;
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
//--------------------------尽量靠前,对应Limit.json的内容---------------------------------------//
// 将json添加到配置中
builder.Configuration.AddJsonFile("Limit.json");
// ip限制
// ip速率限制
builder.Services.Configure<IpRateLimitOptions>(builder.Configuration.GetSection("IpRateLimiting"));
//IP 速率限制策略
builder.Services.Configure<IpRateLimitPolicies>(builder.Configuration.GetSection("IpRateLimitPolicies"));
// 客户端限制
// Client速率限制
builder.Services.Configure<ClientRateLimitOptions>(builder.Configuration.GetSection("ClientRateLimiting"));
// Client 速率限制策略
builder.Services.Configure<ClientRateLimitPolicies>(builder.Configuration.GetSection("ClientRateLimitPolicies"));
//--------------------------尽量靠前,对应Limit.json的内容---------------------------------------//
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
// swagger服务
builder.Services.AddSwaggerGen();
// 缓存服务
builder.Services.AddMemoryCache();
// 将AspNetCoreRateLimit配置到缓存控制中
builder.Services.AddInMemoryRateLimiting();
// 配置单例服务(默认即可)
builder.Services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
//--------------------------限流组件(在跨域之后)---------------------------------------//
// ip限流
app.UseIpRateLimiting();
// client限流
app.UseClientRateLimiting();
//--------------------------限流组件(在跨域之后)---------------------------------------//
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
启动程序
正常访问
访问默认的获取天气接口
返回Body如下:
返回Header如下:
出现红色方框内的数据则限制请求成功
请求限制
以触发10秒内10次的限制进行测试
第11次将会被限制返回数据
返回的限制信息
此处评论已关闭