原文参考:
https://github.com/stefanprodan/AspNetCoreRateLimit(Code)
https://github.com/stefanprodan/AspNetCoreRateLimit/wiki (Wiki)
https://www.getpostman.com/(Http Tool)
解决思路:
Http请求时,通过Header传值(X-ClientId)判断并计数指定接口的调用次数,从而拦截超过设置上限的调用请求。其中,X-ClientId为自定义参数。
参数配置(appsettings.json e.g):
"ClientRateLimiting": { "EnableEndpointRateLimiting": true, "StackBlockedRequests": false, "ClientIdHeader": "X-ClientId", "HttpStatusCode": 429, "EndpointWhitelist": [], "ClientWhitelist": [], "GeneralRules": [ { "Endpoint": "get:/api/services/app/CountActivity/GetCountActivity", "Period": "1s", "Limit": 1 } ] }
服务配置(Startup.cs e.g):
public IServiceProvider ConfigureServices(IServiceCollection services) { services.AddOptions(); services.Configure<ClientRateLimitOptions>(_appConfiguration.GetSection("ClientRateLimiting")); // inject counter and rules stores services.AddSingleton<IClientPolicyStore, DistributedCacheClientPolicyStore>(); services.AddSingleton<IRateLimitCounterStore, DistributedCacheRateLimitCounterStore>(); }
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { app.UseClientRateLimiting(); app.UseMvc(); }
方法重写:
对于拦截过滤有自定义需求时,可以重写ClientRateLimitMiddleware.SetIdentity方法实现
public virtual ClientRequestIdentity SetIdentity(HttpContext httpContext) { var clientId = "anon"; if (httpContext.Request.Headers.Keys.Contains(_options.ClientIdHeader,StringComparer.CurrentCultureIgnoreCase)) { clientId = httpContext.Request.Headers[_options.ClientIdHeader].First(); } return new ClientRequestIdentity { Path = httpContext.Request.Path.ToString().ToLowerInvariant(), HttpVerb = httpContext.Request.Method.ToLowerInvariant(), ClientId = clientId }; }