This is the 12th day of my participation in Gwen Challenge
The introduction
Flow limiting is a common requirement in the use of external Api services.
Limiting the frequency of client access effectively prevents the risk of client scripts or other destructive methods affecting the normal operation of the service.
Traffic limiting can be solved in various ways. The simplest way is to limit Ip addresses. Only one Ip address can be accessed multiple times within a specified period of time.
Of course, we certainly won’t make any wheels ourselves in the development of the species, which is a waste of time, a high probability of error, and not comprehensive consideration. So it’s very important to choose the right wheel. Today I recommend a solution to ASP.NET Core speed limit **AspNetCoreRateLimit **
AspNetCoreRateLimit introduction
AspNetCoreRateLimit is an ASP.NET Core rate limiting solution designed to control the rate at which clients make requests to Web API or MVC applications based on IP addresses or client ids. AspNetCoreRateLimit contains a IpRateLimitMiddleware and ClientRateLimitMiddleware, every middleware can according to the different scenarios with limit allows IP or client, custom these limit the strategy, You can also apply restriction policies to each API URL or specific HTTP Method.
Nuget package
Nuget package reference, as of article use AspNetCoreRateLimit version 3.2.2.
Install-Package AspNetCoreRateLimit
Copy the code
Configuration instructions
General Ip configuration rules
IpRateLimiting
The name of the | type | instructions |
---|---|---|
EnableEndpointRateLimiting | bool | False then restrictions are applied globally and only rules with endpoints * are applied. For example, if you set a limit of five calls per second, any HTTP calls to any endpoint will count toward that limit True then the restriction applies to each endpoint, such as {HTTP_Verb}{PATH}. For example, if you set a limit of 5 calls per second for the *:/ API /values client |
StackBlockedRequests | bool | True If you want rejected API calls to count toward display at other times (minutes, hours, etc.) False Rejected API calls are not added to the count of calls; If the client makes three requests per second and you set a limit of one call per second, other limits such as per-minute or daily counters will only record the first call, the successful API call |
RealIpHeader | string | Behind the server is a reverse proxy, if your proxy server uses a different header then extracts the client IP x-real-IP use this option to set |
ClientIdHeader | string | Obtain the CLIENT ID from the whitelist. If there is a client ID in this header and it matches the value specified in ClientWhitelist, no rate limit is applied. |
HttpStatusCode | string | Restricted status code |
IpWhitelist | string | IP whitelist: IP V4 and V6 are supported |
EndpointWhitelist | string | Endpoint whitelist |
ClientWhitelist | string | Whitelist of white clients |
GeneralRules | json | General rules |
QuotaExceededResponse | json | Customize what is returned “QuotaExceededResponse”: { “Content” : “{{” code” : 429, “MSG” : “visit too frequently, please try again later”, “data” : null}} “, “ContentType”: “application/json”, “StatusCode”: 200 } |
For reference, the following configuration files represent the following: IP restrictions apply globally and the rule is 3 accesses every 5 seconds
{ "IpRateLimiting": { "EnableEndpointRateLimiting": false, "StackBlockedRequests": false, "RealIpHeader": "X-real-ip ", "ClientIdHeader":" X-Clientid ", "HttpStatusCode": 429, ////IP whitelist: supports IP V4 and v6 "IpWhitelist": [" 127.0.0.1 "], "GeneralRules" : [{" Endpoint ":" * ", "Period" : "5 s", "Limit" : 3}]}}Copy the code
GeneralRules
The name of the | type | instructions |
---|---|---|
Endpoint | string | The endpoint path |
Period | string | Time segment, format: {number}{unit}; Available units: S, M, H, D |
Limit | string | Call limit |
EndPoint
Endpoint format :{HTTP_Verb}:{PATH}, you can use the Asterix symbol to locate any HTTP predicate.
Period
Period format: {INT}{PERIOD_TYPE}, you can use one of the following period types: S, m, h, d.
Limit
Limit format: {LONG}
Configuration Rule Reference
"GeneralRules": [// Can only be accessed 2 times per second {"Endpoint": "*", "Period": "1s", // Limit" Limit": 2}, // Can only be called 100 times in 15 minutes {"Endpoint": "*", "Period", "15 m", "Limit" : 100}, 12 h can call 1000 / / {" Endpoint ":" * ", "Period" : "12 h", "Limit" : 1000}, can call 10000 times 7 days / / {" Endpoint ":" * ", "Period" : "7 d", "Limit" : 10000}, / / API/rateLimit/GetDateTime interface rules for 5 seconds at most visit three {" Endpoint ":" * : / API/rateLimit GetDateTime ", "Period" : "5s", "Limit": 3 } ]Copy the code
Special Ip address restriction rule
"IpRateLimitPolicies": {//IP Rules": [{//IP "IP ": "84.247.85.224", // Rules content "Rules": [//1s request 10 times {"Endpoint": "*", "Period" : "1 s", "Limit" : 10}, / / 15 minutes request 200 {" Endpoint ":" * ", "Period" : "15 m", "Limit" : 200}}, {/ / IP support set up multiple "IP" : "192.168.3.22/25", "Rules" : [/ / 1 second request 5 times {" Endpoint ":" * ", "Period" : "1 s", "Limit" : 5}, / / 15 minutes request {150 times "Endpoint" : "*", "Period", "15 m", "Limit" : 150}, 12 hours / / request 500 {" Endpoint ":" * ", "Period" : "12 h", "Limit" : 500}]]}}Copy the code
I believe that after reading the general Ip configuration rules of partners to see this section of configuration should be no pressure, I will not do more explanation here.
Using special Ip restriction rules requires enabling this code in ConfigureService
// Load a customized IP address restriction policy, that is, a special restriction for a certain IP address. //services.Configure<IpRateLimitPolicies>(configuration.GetSection("IpRateLimitPolicies"));Copy the code
Encoding to use
With the basic rules in mind, we started coding
1. Injection service
Because of the amount of injection involved, we use an extended method to identify what the Ip limit service needs to inject.
public static class RateLimitedConfigureService { public static void RateLimitedConfig(this IServiceCollection services, IConfiguration Configuration) {// Configuration mode config services.addOptions (); // Storage rate-limiting calculator and IP rule services.addMemoryCache (); Configure<IpRateLimitOptions>(configuration.GetSection(" ipratelimitating ")); // Load a customized IP address restriction policy, that is, a special restriction for a certain IP address. //services.Configure<IpRateLimitPolicies>(configuration.GetSection("IpRateLimitPolicies")); AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>(); services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>(); AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>(); }}Copy the code
1.1 Configuring Services
Public void ConfigureServices (IServiceCollection services) {/ / Ip restrictions configuration services. RateLimitedConfig (_configuration); services.AddControllers(); }Copy the code
1.2 Enabling Pipes
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); // Enable client IP limit rate app.useipratelimiting (); }Copy the code
2. Write an Api
// </summary> [Route(" API /rateLimit")] [ApiController] public Class RateLimitController: Controller { [HttpGet("GetDateTime")] public string GetDateTime() { return DateTime.Now.ToString("d"); }}Copy the code
3, test,
Normal request
Call http://localhost:5000/api/ratelimit/getdatetime request interface, returns the current date.
If F12 is used to check ResponseHeaders, we can find that three parameters are added, respectively representing the meaning of
X-rate-limit-limit Indicates the Limit time range
X-rate-limit-remaining Indicates the number of Remaining requests
X-rate-limit-reset Indicates the request Reset time
Each time x-rate-limit-remaining is called minus 1, an error is returned when no number of requests can be called.
API calls quota exceeded! maximum admitted 3 per 5s.
Copy the code
Bad request
The page returns an error message when the number of requests is outside the time limit. The returned content can also be customized. For details, see Configuration Rules
reference
Asp.NET Core flow limiting control -AspNetCoreRateLimit
NetCore and AspNetCoreRateLimit implement traffic limiting