我倾向于频率限制方案,因为它简单有效,能实时阻挡暴力破解,同时结合Redis的高性能存储临时计数数据,避免了黑名单的维护成本和行为分析的复杂性。下面是基于Redis的登录频率限制实现代码示例: using StackExchange.Redis; public class LoginLimiter { private readonly IDatabase _db; private readonly int _maxAttempts = 5; private readonly TimeSpan _lockoutTime = TimeSpan.FromMinutes(15); public LoginLimiter(IDatabase db) { _db = db; } public async Task<bool> IsAllowedAsync(string username) { var key = $"login_attempts:{username}"; var attempts = await _db.StringIncrementAsync(key); if (attempts == 1) { await _db.KeyExpireAsync(key, _lockoutTime); } return attempts <= _maxAttempts; } public async Task ResetAttemptsAsync(string username) { var key = $"login_attempts:{username}"; await _db.KeyDeleteAsync(key); } }
来源1
黑名单方案:将恶意IP或用户存入Redis set集合,登录时先判断是否存在。简单但有问题:如何判断恶意?IP容易变,用户无辜被封。SET ip_blacklist member_ip EXPIRE 3600 判断IF MEMBER ip_blacklist $ip
来源2
频率限制是最实用的。用Redis的String类型记录尝试次数,超过阈值锁定一段时间。比如key=login:ip:192.168.1.1,INCR后检查>5就拒绝,SETEX 锁定。优点实时,缺点纯暴力破解下仍需几秒配合验证码更好。
来源3
行为分析高级点,用Redis Hash存用户行为分数:异常登录时间+1,异地+2,高频失败+3,总分超阈值封禁。但实现复杂,需要机器学习模型,不适合中小项目。频率限制是入门首选。
来源4
综合方案:频率限制为主,黑名单为辅。Redis ZSET 存失败记录,按时间score排序,清理旧数据。Lua脚本原子性检查: local attempts = redis.call('INCR', KEYS[1]) if attempts == 1 then redis.call('EXPIRE', KEYS[1], 300) end if attempts > 10 then return 0 end return 1
来源5
我用过频率限制,针对同一个IP或用户ID,5分钟内最多3次失败,用Redis pipeline批量操作:HINCRBY attempts:ip $ip 1,HEXPIRE如果超限。黑名单只针对已确认攻击IP。
来源6
行为分析:监控登录失败后的后续请求模式,Redis List存日志,分析熵值判断脚本攻击。但成本高,倾向频率限制+短信验证组合拳。
FAQ
Q: 频率限制怎么处理分布式系统?
A: 用Redis Cluster统一计数,所有节点共享key。
Q: 黑名单怎么自动清理?
A: 用SET或ZSET加expire,或定时任务扫描删除过期。
Q: 行为分析需要什么数据?
A: IP、UA、时间间隔、失败次数等,存Redis Hash实时计算分数。
Q: 哪个最省资源?
A: 频率限制,单key操作快。