很多时候,为了避免自己的系统被恶意频繁的请求,我们都会对请求做 限流/限速 处理,比如 1s 内,同个接口或者全部接口最多只能请求 1次,超过的话返回对应的错误提示。
实现方式(主要说明 AspNetCoreRateLimit 的方式)
一.自己手动实现
自己实现的话,一般就是通过记录用户的 ip 或者 clientId,对每次请求进行记录(记录请求ip,clientId 时间等,记录可写在缓存,也可以是数据库如 redis),重写拦截器,进行判断处理,符合超过限制规则的话,则返回对应错误(也可以通过漏桶算法实现)
二.AspNetCoreRateLimit
直接使用中间件,引入 nuget,进行简单的配置即可(参考官方文档 https://github.com/stefanprodan/AspNetCoreRateLimit)
具体实现方式可参考文档,几乎按照文档的来便可完成,这里简单说明下关于 appsettings.json 上的配置
以 IpRateLimit 为例(ClientIdRateLimit 类似,只是几点的关键词不同)
"IpRateLimiting": { "EnableEndpointRateLimiting": ture, //ture 针对每个接口独立限速,false 全局接口累计限速 "StackBlockedRequests": false, //false 拒绝的API调用不会添加到调用次数计数器上 "RealIpHeader": "X-Real-IP", "ClientIdHeader": "X-ClientId", "HttpStatusCode": 200, "QuotaExceededResponse": { //自定义返回的错误内容 "Content": "{{\"code\":1,\"message\":\"请求过于频繁,请稍后重试\",\"data\":\"\"}}", "ContentType": "application/json", "StatusCode": 200 }, "IpWhitelist": [ "127.0.0.1", "::1/10", "192.168.0.0/24" ], //ip白名单 "EndpointWhitelist": [ "get:/api/license", "*:/api/status" ],//请求路径白名单 "ClientWhitelist": [ "dev-id-1", "dev-id-2" ],//客户度id白名单 "GeneralRules": [ //具体的策略,根据不同需求配置不同端点即可 { "Endpoint": "*", "Period": "1s", //Period的单位可以是s, m, h, d "Limit": 2 //Limit是单位时间内的允许访问的次数 } ] }, "IpRateLimitPolicies": { //指定ip规则 "IpRules": [ { "Ip": "84.247.85.224", "Rules": [ { "Endpoint": "*", "Period": "1s", "Limit": 10 } ] } ] }
tip:这里可能会遇到个跨域失败问题,这个时候需要将 app.UseClientRateLimiting(); 放到 app.UseCors(); 下面即可,让 允许跨域规则 优先生效