public class RedisIpPolicyStore : IIpPolicyStore { private readonly IpRateLimitOptions _options; private readonly IpRateLimitPolicies _policies; private readonly RedisCache _redisCache; public RedisIpPolicyStore( IOptions<IpRateLimitOptions> options = null, IOptions<IpRateLimitPolicies> policies = null) { _options = options?.Value; _policies = policies?.Value; _redisCache = new RedisCache(); } public async Task<bool> ExistsAsync(string id, CancellationToken cancellationToken = default) { return await _redisCache.KeyExistsAsync($"{_options.IpPolicyPrefix}", 0); } public async Task<IpRateLimitPolicies> GetAsync(string id, CancellationToken cancellationToken = default) { string stored = await _redisCache.GetStringAsync($"{_options.IpPolicyPrefix}", 0); if (!string.IsNullOrEmpty(stored)) { return JsonConvert.DeserializeObject<IpRateLimitPolicies>(stored); } return default; } public async Task RemoveAsync(string id, CancellationToken cancellationToken = default) { await _redisCache.DelStringAsync($"{_options.IpPolicyPrefix}", 0); } public async Task SeedAsync() { // on startup, save the IP rules defined in appsettings if (_options != null && _policies != null) { await _redisCache.SetStringAsync($"{_options.IpPolicyPrefix}", JsonConvert.SerializeObject(_policies), 0).ConfigureAwait(false); } } public async Task SetAsync(string id, IpRateLimitPolicies entry, TimeSpan? expirationTime = null, CancellationToken cancellationToken = default) { var exprie = expirationTime.HasValue ? Convert.ToInt32(expirationTime.Value.TotalSeconds) : -1; await _redisCache.SetStringAsync($"{_options.IpPolicyPrefix}", JsonConvert.SerializeObject(_policies), 0, exprie); } }
3、客户端特殊规则public class RedisClientPolicyStore : IClientPolicyStore { private readonly ClientRateLimitOptions _options; private readonly ClientRateLimitPolicies _policies; private readonly RedisCache _redisCache; public RedisClientPolicyStore( IOptions<ClientRateLimitOptions> options = null, IOptions<ClientRateLimitPolicies> policies = null) { _options = options?.Value; _policies = policies?.Value; _redisCache = new RedisCache(); } public async Task<bool> ExistsAsync(string id, CancellationToken cancellationToken = default) { return await _redisCache.KeyExistsAsync($"{_options.ClientPolicyPrefix}", 0); } public async Task<ClientRateLimitPolicy> GetAsync(string id, CancellationToken cancellationToken = default) { string stored = await _redisCache.GetStringAsync($"{_options.ClientPolicyPrefix}", 0); if (!string.IsNullOrEmpty(stored)) { return JsonConvert.DeserializeObject<ClientRateLimitPolicy>(stored); } return default; } public async Task RemoveAsync(string id, CancellationToken cancellationToken = default) { await _redisCache.DelStringAsync($"{_options.ClientPolicyPrefix}", 0); } public async Task SeedAsync() { // on startup, save the IP rules defined in appsettings if (_options != null && _policies != null) { await _redisCache.SetStringAsync($"{_options.ClientPolicyPrefix}", JsonConvert.SerializeObject(_policies), 0).ConfigureAwait(false); } } public async Task SetAsync(string id, ClientRateLimitPolicy entry, TimeSpan? expirationTime = null, CancellationToken cancellationToken = default) { var exprie = expirationTime.HasValue ? Convert.ToInt32(expirationTime.Value.TotalSeconds) : -1; await _redisCache.SetStringAsync($"{_options.ClientPolicyPrefix}", JsonConvert.SerializeObject(_policies), 0, exprie); } }
之后在Startup文件中增加对应的注入
services.AddSingleton<IRateLimitCounterStore, RedisRateLimitCounterStore>(); services.AddSingleton<IIpPolicyStore, RedisIpPolicyStore>(); services.AddSingleton<IClientPolicyStore, RedisClientPolicyStore>();
之后运行就可以在redis中看到啦
五、修改规则规则只能修改IP和客户端的特殊规则,因为上一部分已经注入了改规则的对应redis增删查改的功能,所以我们可以利用这些方法重写规则,如下: