前言
在构建API项目时,有时出于安全考虑,防止访问用户恶意攻击,希望限制此用户ip地址的请求次数,减轻拒绝服务攻击可能性,也称作限流。接下来,我们就来学习开源库DotNetRateLimiter
如何轻松实现限流。
项目使用配置
安装Nuget包
在新建立的WebAPI
项目中,通过Nuget
包管理器安装DotNetRateLimiter,安装命令:
NuGet\Install-Package DotNetRateLimiter -Version 1.0.7
项目服务注入
C#
using DotNet.RateLimiter;
var builder = WebApplication.CreateBuilder(args);
//DotNetRateLimiter配置
builder.Services.AddRateLimitService(builder.Configuration);
DotNetRateLimiter 配置:
appsetting.json 文件中,添加JSON对象节点进行配置,如下:
Json
"RateLimitOption": {
"EnableRateLimit": true, //是否开启
"HttpStatusCode": 429,//http响应码
"ErrorMessage": "请求次数过多", //响应信息
"IpHeaderName": "X-Forwarded-For",//客户端IP请求头
//"RedisConnection": "127.0.0.1:6379", 默认使用内存缓存,并且支持配置 Redis 连接, 这样可以对分布式应用进行限流。
"IpWhiteList": ["::1"], //设置白名单集合
"ClientIdentifier": "X-Client-Id"
}
到此配置已经完成,非常简单,接下就是在项目中如何进行使用。
项目中使用
控制器Controller上使用
这个控制器20秒内只允许 3 个请求, 如果调用 api 超过 3 次,就会收到http错误请求代码: 429,错误信息:请求次数过多
C#
[Route("api/[controller]")]
[ApiController]
[RateLimit(PeriodInSec = 20, Limit = 3, Scope = RateLimitScope.Controller)]//控制器上使用
public class RateLimiterController : ControllerBase
{
}
接口Action上使用
这个接口20秒内只允许 3 个请求, 如果调用 api 超过 3 次,就会收到http错误请求代码: 429,错误信息:请求次数过多
C#
/// <summary>
/// 添加RateLimit接口特性
/// </summary>
/// <returns></returns>
[HttpGet]
[Route("GetNow")]
[RateLimit(PeriodInSec = 20, Limit = 3)]
public ActionResult GetNow()
{
return Ok(
new
{
Msg = "当前时间",
Value = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")
}
);
}
/// <summary>
/// 不添加RateLimit特性接口
/// </summary>
/// <returns></returns>
[HttpGet]
[Route("GetYesteyDayNow")]
public ActionResult GetYesteyDayNow()
{
return Ok(
new
{
Msg = "昨天时间",
Value = DateTime.Now.AddDays(-1).ToString("yyyy/MM/dd HH:mm:ss")
}
);
}
/// <summary>
/// RateLimit特性结合路由参数接口
/// </summary>
/// <param name="day"></param>
/// <returns></returns>
[HttpGet]
[Route("GetBeforeTimeByDay/{day}")]
[RateLimit(PeriodInSec = 20, Limit = 3, RouteParams = "day")]//搭配路由进行使用
public ActionResult ActionResult(int day)
{
return Ok(
new
{
Msg = $"{day}天前时间",
Value = DateTime.Now.AddDays(-day).ToString("yyyy/MM/dd HH:mm:ss")
}
);
}
测试验证
打开Swagger,调用接口测试: