fix: 登录频率限制 bug — lock_until=0 导致计数被清零

根因: 初始 lock_until=0 时 now >= 0 + 60 恒为真, 每次请求都清除计数
修复: lock_until 改用 None 表示未锁定, 仅非 None 时做过期判断

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
qinglong
2026-06-13 13:46:29 +08:00
parent a75b9d0975
commit 2f9063d6d4
3 changed files with 36 additions and 8 deletions
+8 -4
View File
@@ -24,20 +24,24 @@ def _check_rate_limit(ip: str) -> bool:
entry = _LOGIN_FAILS.get(ip)
if entry:
fail_count, lock_until = entry
if now < lock_until:
if lock_until and now < lock_until:
return False # still locked
if now >= lock_until + _LOCK_SECONDS:
_LOGIN_FAILS.pop(ip, None) # expired, reset
if lock_until and now >= lock_until:
_LOGIN_FAILS.pop(ip, None) # lock expired, reset
return True
def _record_fail(ip: str):
now = time.time()
entry = _LOGIN_FAILS.get(ip, [0, 0])
entry = _LOGIN_FAILS.get(ip)
if entry is None:
entry = [0, None]
entry[0] += 1
if entry[0] >= _MAX_FAILS:
entry[1] = now + _LOCK_SECONDS
logger.warning(f"🔒 IP {ip} 登录锁定 {_LOCK_SECONDS}s ({_MAX_FAILS} 次失败)")
else:
logger.debug(f"IP {ip} 登录失败计数: {entry[0]}/{_MAX_FAILS}")
_LOGIN_FAILS[ip] = entry