“This article has participated in the good article call order activity, click to see: back end, big front end double track submission, 20,000 yuan prize pool for you to challenge!”

The introduction

Traffic limiting is a requirement that is often encountered in the use of external Api services.

Limiting the frequency of client access can effectively prevent the risk that the client will use scripts or other destructive methods to affect the normal operation of the service.

There are many ways to limit traffic. The simplest way is to restrict Ip access. Ip access records can be stored in memory or other high-speed data storage services.

Of course, we will certainly not build any wheel in the development, both a waste of time, error probability is large, not comprehensive consideration. So choosing the right wheel is very important, and today I recommend AspNetCoreRateLimit, an ASP.NET Core rate limiting solution

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 address or client ID. 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 a restriction policy to each API URL or specific HTTP Method.

Nuget package

Nuget package reference, AspNetCoreRateLimit version 3.2.2 at the time of article use.

Install-Package AspNetCoreRateLimit 
Copy the code

Configuration instructions

General Ip configuration rules

IpRateLimiting

The name of the type instructions
EnableEndpointRateLimiting bool False applies the restriction globally, and only rules that have an endpoint * are applied. For example, if you set a limit of five calls per second, then any HTTP calls to any endpoint will count toward that limit true and the limit will apply 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 False Rejected API calls are not added to the call count; If the client makes three requests per second and you set a limit of one call per second, other limits such as a per-minute or per-day counter will only record the first call, the successful API call
RealIpHeader string The back of the server is a reverse proxy, if your proxy server uses a different header then extract the client IP x-real-IP use this option to set it
ClientIdHeader string Obtains the ID of the whitelist client. If there is a client ID in this header and it matches the value specified in the ClientWhitelist, no rate limit is applied.
HttpStatusCode string Restricted status code
IpWhitelist string IP whitelist: Supports IP V4 and V6
EndpointWhitelist string Endpoint whitelist
ClientWhitelist string White Client whitelist
GeneralRules json General rules
QuotaExceededResponse json “QuotaExceededResponse”: {” Content”: “{{“code”:429,” MSG “:” too often, please try again later “,”data”:null}}”, “ContentType”: “application/json”, “StatusCode”: 200 }

For details, see the following configuration files: The IP address restriction applies to all global Settings. The rule is three access times every five seconds

{ "IpRateLimiting": { "EnableEndpointRateLimiting": false, "StackBlockedRequests": false, "RealIpHeader": "X-real-ip ", "ClientIdHeader":" X-Clientid ", "HttpStatusCode": 429, ////IP whitelist: support 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 Period, format: {number}{unit}; Available units: S, m, H, d
Limit string Call limit

EndPoint

Endpoint format :{HTTP_Verb}:{PATH}, you can use asterix symbols 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

Restricted format: {LONG}

Configuration Rule Reference

"GeneralRules" : [/ / 1 seconds can only access 2 times {" Endpoint ":" * ", "Period" : "1 s", / / limits "Limit", 2}, {/ / 15 minutes can only call 100 times "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 restriction rules

"IpRateLimitPolicies": {//IP Rules" IpRules": [{//IP "IP ": "84.247.85.224", // Rule content "Rules": [//1s requests 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 the small partners to see this section of the configuration should not have any pressure, I will not do much explanation here.

This code is enabled in the ConfigureService to use special Ip restriction rules

// Load the IP limit custom policy, that is, for a specific IP limit, //services.Configure<IpRateLimitPolicies>(configuration.getSection ("IpRateLimitPolicies"));Copy the code

Encoding to use

With the ground rules in mind, we start coding

1. Inject services

Because of the large amount of injected content involved, we use an extension method to identify the content that the Ip limiting service needs to inject.

public static class RateLimitedConfigureService { public static void RateLimitedConfig(this IServiceCollection services, {// configuration of IConfiguration mode services.addOptions (); // Memory rate limit calculator and IP rule services.addMemoryCache (); // Configure<IpRateLimitOptions>(configuration.getSection ("IpRateLimiting")); // Configure<IpRateLimitOptions>(configuration. // Load the IP limit custom policy, that is, for a specific IP limit, //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(); // Pipeline events enable client IP limiting 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 we look at the ResponseHeaders at F12, we can see that we have three more parameters

X-rate-limit-limit Specifies the time Limit

X-rate-limit-remaining Indicates the number of Remaining requests

X-rate-limit-reset Indicates the request Reset time

Every time x-rate-limit-remaining is called, subtract 1. When no number of requests can be called, an error is returned.

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 falls 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 combined with AspNetCoreRateLimit implements traffic limiting