React登录限制如何防止频繁尝试导致接口被攻击?

UX凌薇 阅读 213

我给登录表单加了防抖和错误次数限制,但测试时发现攻击者还是能不断重试,这是为什么?

现在用useState记录错误次数,超过3次就禁用按钮,还用了防抖处理:


const Login = () => {
  const [attempts, setAttempts] = useState(0);
  
  const handleSubmit = useCallback(debounce(async (e) => {
    e.preventDefault();
    try {
      await loginApi(loginForm);
    } catch (err) {
      setAttempts(prev => prev +1);
      if(attempts >=3) disableForm();
    }
  }), [loginForm]);

  return (
    <form onSubmit={handleSubmit}>
      {/* 表单字段 */}
      {attempts <3 ? <button>登录</button> : '尝试次数过多'}
    </form>
  );
};

但用Postman疯狂请求接口时,错误次数没被记录,后端说被攻击了。前端的这种限制根本没起作用啊,是不是应该加验证码?或者服务端也要做限流?

我来解答 赞 8 收藏
二维码
手机扫码查看
1 条解答
百里红运
你这个问题很常见,前端防抖和错误次数限制其实只是用户体验层面的措施,**根本防不住接口被攻击**。攻击者用 Postman 或脚本直接调用登录接口,完全绕过了你前端的 attempts 计数和按钮禁用逻辑,所以你看到的“限制”根本不起作用。

要真正防止暴力破解攻击,必须在**服务端做限流和验证机制**,前端的限制只是锦上添花。下面是关键步骤:

### 1. 后端必须做接口限流(Rate Limit)
- 比如每个 IP 每分钟最多请求登录接口 10 次
- 超出限制直接返回 429
- 可用中间件如 Express 的 rate-limiter-flexible,或者用 Nginx 限流

### 2. 登录失败次数过多,要记录在服务端
- 用 Redis 记录用户/IP 的失败次数
- 比如连续失败 5 次,锁定账户或返回验证码挑战
- 前端的 attempts 控制只是辅助,不能作为唯一限制

### 3. 加验证码(推荐)
- 登录失败达到一定次数后触发验证码(reCAPTCHA、极验、点选验证码等)
- 验证码必须服务端验证通过才允许继续登录流程

### 4. 避免爆破账户,登录接口不要暴露是否存在该用户
- 无论用户名是否存在、密码是否正确,都统一返回“用户名或密码错误”
- 避免攻击者用来探测有效账户

---

你现在的 React 代码虽然加了防抖和尝试次数,但这些状态都保存在浏览器内存里,攻击者绕过去非常容易。你可以在前端保留这些逻辑提升体验,但一定要加后端防护,不然就像“给大门装了锁,窗户却开着”。

建议你和服务端一起改,加限流和验证码,这才是完整的防御。
点赞 5
2026-02-04 12:01