很多时候,为了避免自己的系统被恶意频繁的请求,我们都会对请求做 限流/限速 处理,比如 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(); 下面即可,让 允许跨域规则 优先生效