This demo shows how how to use Redis in .NET 5 to implement IP Rate limiting to prevent excessive calls to your app from a single client.
- Frontend: ASP.NET Core MVC
- Backend: ASP.NET Core MVC / Redis
-
New responses are added key-ip:
SETNX your_ip:PING limit_amount
- E.g
SETNX 127.0.0.1:PING 10
more information
- E.g
-
Set a timeout on key:
EXPIRE your_ip:PING timeout
- E.g
EXPIRE 127.0.0.1:PING 1000
more information
- E.g
-
Next responses are get bucket:
GET your_ip:PING
- E.g
GET 127.0.0.1:PING
more information
- E.g
-
Next responses are changed bucket:
DECRBY your_ip:PING amount
- E.g
DECRBY 127.0.0.1:PING 1
more information
- E.g
When configuring constructing our app's middleware in Startup.cs, we initialize the cache client and inject it into our services. We then pull from the configuration the IpRateLimit
section, and use that as the configuration for IpRateLimitOptions
using AspNetCoreRateLimit;
// ...
services.AddStackExchangeRedisCache(options =>
{
options.ConfigurationOptions = ConfigurationOptions.Parse(redisConnectionUrl);
});
services.Configure<IpRateLimitOptions>(Configuration.GetSection("IpRateLimit"));
services.AddSingleton<IIpPolicyStore, DistributedCacheIpPolicyStore>();
services.AddSingleton<IRateLimitCounterStore, DistributedCacheRateLimitCounterStore>();
services.AddSingleton<IRateLimitConfiguration,RateLimitConfiguration>();
//...
app.UseIpRateLimiting();
The IpRateLimit
section is from the appsettings.json
file:
"IpRateLimit": {
"EnableEndpointRateLimiting": true,
"StackBlockedRequests": false,
"RealIPHeader": "X-Real-IP",
"ClientIdHeader": "X-ClientId",
"HttpStatusCode": 429,
"GeneralRules": [
{
"Endpoint": "*:/api/*",
"Period": "10s",
"Limit": 10
}
]
}
This section dictates the period the path which limitations will be applied to, Endpoint
, the period over which restrictions are considered, Period
, and the Limit for the number of requests permitted in that period Limit
git clone https://github.com/redis-developer/basic-redis-rate-limiting-demo-csharp-dot-net.git
REDIS_ENDPOINT_URL = "Redis server URI:PORT"
REDIS_PASSWORD = "Password to the server"
dotnet run
Static content runs automatically with the backend part.