支付密码防暴力破解需前后端协同:前端做体验优化(如倒计时、禁用按钮),但不可信;后端用redis持久化锁定状态并校验;前后端通过轻量接口同步锁态;叠加ip限频、禁用自动填充、二次验证等安全措施。

支付密码输错多次后锁定,核心是前端防暴力+后端校验+状态同步,不能只靠前端计数。
前端限制输入频率和次数
用户在页面连续输错时,前端可做体验优化,比如禁用输入框、显示倒计时、提示剩余尝试次数。但这些纯属提示,不可信——攻击者可绕过 JS 直接发请求。
- 每次提交后记录本地错误次数(如 localStorage),配合时间戳判断是否过期(例如 15 分钟内最多 5 次)
- 输错 3 次后禁用提交按钮,显示“还剩 2 次机会”,第 5 次后显示“已锁定,请 15 分钟后再试”
- 用 Date.now() 计算锁定起始时间,避免依赖服务端时间不同步导致倒计时不准
后端必须校验并统一管理锁定状态
真正有效的锁定逻辑必须落在服务端。每次密码校验请求进来,都要查该用户当前是否处于锁定期,且失败次数要持久化(如 Redis 记录:`lock:uid:123 → {count:4, expireAt:1735689200}`)。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 校验前先检查 Redis 中是否存在有效锁定 key,有则直接返回锁定响应(HTTP 423 或自定义 code)
- 校验失败时,原子性地递增失败计数,并设置过期时间(如 SETEX lock:uid:123 900 '4')
- 校验成功则清空该用户的锁定记录(DEL lock:uid:123)
前后端状态保持一致
前端显示的“已锁定”必须和服务端实际状态一致,否则用户会困惑。推荐做法是:每次进入密码页或聚焦输入框时,主动请求一个轻量接口(如 /api/payment/lock-status),获取当前锁定剩余时间或是否可重试。
- 接口返回 { locked: true, remainingSeconds: 482 },前端据此渲染倒计时或禁用态
- 避免前端自行推算锁定结束时间,防止因本地时间不准或页面长时间未刷新导致状态错乱
- 若后端发现用户已解锁,但前端仍显示锁定,可触发一次自动重置 UI
安全增强建议
仅限输错次数还不够,需叠加其他防护降低爆破风险。
- 对同一 IP + 用户组合,增加短时请求频次限制(如 1 分钟最多 10 次校验请求)
- 密码字段使用 type="password",禁止 autocomplete,避免浏览器自动填充错误密码反复提交
- 敏感操作(如支付确认)建议二次验证,比如短信/生物识别,不单依赖支付密码
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










