vs2022 搭建NET6 WebApi 接口项目《五》 接口访问限流配置


1、在appsetting.json中配置参数

     

 "IpRateLimiting": {
    //false则全局将应用限制,并且仅应用具有作为端点的规则* 。 true则限制将应用于每个端点,如{HTTP_Verb}{PATH}
    "EnableEndpointRateLimiting": true,
    //false则拒绝的API调用不会添加到调用次数计数器上
    "StackBlockedRequests": false,
    //注意这个配置,表示获取用户端的真实IP,我们的线上经过负载后是 X-Forwarded-For,而测试服务器没有,所以是X-Real-IP
    "RealIpHeader": "X-Real-IP",
    "ClientIdHeader": "X-ClientId",
    "HttpStatusCode": 200, //设置返回状态码
    //"QuotaExceededResponse": {
    //  "Content": "{{\"code\":429,\"msg\":\"访问过于频繁,请稍后重试\",\"data\":null}}",
    //  "ContentType": "application/json",
    //  "StatusCode": 200
    //},//返回提示信息
    "IpWhitelist": [], //限制白名单,在名单中的IP,则无访问权限
    "EndpointWhitelist": [],
    "ClientWhitelist": [],
    "GeneralRules": [
      {
        "Endpoint": "*", //对所有接口进行监控
        "Period": "10s",
        "Limit": 5
      }
    ]
  },

2、在program.cs中配置

     

#region 限流配置
//加载配置
builder.Services.AddOptions();
//services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);//设置兼容性版本
builder.Services.AddMemoryCache();
//加载IpRateLimiting配置
builder.Services.Configure(configuration.GetSection("IpRateLimiting"));
//注入计数器和规则存储
builder.Services.AddSingleton();
builder.Services.AddSingleton();
//添加框架服务
builder.Services.AddMvc();
// clientId / clientIp解析器使用它。
builder.Services.AddSingleton();
//配置(计数器密钥生成器)
builder.Services.AddSingleton();
#endregion

3、新建一个IPLimitMiddleware类

    

public class IPLimitMiddleware : IpRateLimitMiddleware
    {
        private readonly IpRateLimitOptions _options;
        private readonly IIpPolicyStore _ipPolicyStore;

        public IPLimitMiddleware(RequestDelegate next,IProcessingStrategy strategy, IOptions options, IIpPolicyStore policyStore, IRateLimitConfiguration config, ILogger logger)
            : base(next, strategy, options, policyStore, config, logger)
        {
            _options = options.Value;
            _ipPolicyStore = policyStore;
        }

        public override Task ReturnQuotaExceededResponse(HttpContext httpContext, RateLimitRule rule, string retryAfter)
        {
            var ip = httpContext.Request.Headers["X-Forwarded-For"].FirstOrDefault();
            if (string.IsNullOrEmpty(ip))
            {
                ip = httpContext.Connection.RemoteIpAddress.ToString();
            }

            //后面需要将IP添加到数据库中进行监控,以便对非法IP进行限制

            httpContext.Response.ContentType = "application/json";
            return httpContext.Response.WriteAsync($"{{ \"code\": 429,\"msg\": \"访问过于频繁,请稍后重试\",\"data\":null }}");
            //httpContext.Response.Headers.Append("Access-Control-Allow-Origin", "*");
            //return base.ReturnQuotaExceededResponse(httpContext, rule, retryAfter);
        }
    }

这里不太好测试,就只贴代码