背景与价值登录接口易遭受暴力破解。基于账号与设备特征实施渐进式锁定与速率控制,可有效阻断攻击并保持可用性。统一规范维度:账号ID与设备指纹双维度计数与锁定。渐进策略:失败次数越多,锁定时间窗口越长,上限封禁。白名单例外:受控IP或设备在低风险场景下放宽阈值。核心实现锁定器type Key = string
type Clock = () => number
class Lock {
clock: Clock
fails = new Map<Key, number>()
until = new Map<Key, number>()
constructor(clock: Clock = () => Date.now()) { this.clock = clock }
reset(k: Key) { this.fails.set(k, 0); this.until.delete(k) }
fail(k: Key) {
const n = (this.fails.get(k) || 0) + 1
this.fails.set(k, n)
const baseMs = 1000
const dur = Math.min(60_000, baseMs * Math.pow(2, Math.floor(n / 3)))
this.until.set(k, this.clock() + dur)
}
locked(k: Key): boolean { const u = this.until.get(k) || 0; return this.clock() < u }
count(k: Key): number { return this.fails.get(k) || 0 }
}
速率限制与维度组合type Attempt = { account: string; device: string; success: boolean }
class Gate {
accountLock = new Lock()
deviceLock = new Lock()
allowIp = new Set<string>(['203.0.113.10'])
try(attempt: Attempt, ip: string): boolean {
const ak = 'a:' + attempt.account
const dk = 'd:' + attempt.device
if (this.allowIp.has(ip)) return true
if (this.accountLock.locked(ak) || this.deviceLock.locked(dk)) return false
if (!attempt.success) { this.accountLock.fail(ak); this.deviceLock.fail(dk) } else { this.accountLock.reset(ak); this.deviceLock.reset(dk) }
return true
}
}
落地建议双维度锁定与速率限制结合,异常设备与账号同时触发冷却窗口。渐进式加长锁定时间,避免无限制尝试;成功登录重置计数。在受控IP环境下适度放宽阈值,但保留审计与限速。验证清单失败次数是否触发渐进式锁定并随次数增长而延长。正常用户在成功登录后是否立即解除锁定与计数。

发表评论 取消回复