---
title: 验证码接口限流怎么做才不折腾正常用户
site: 星湖の小窝
category: 后端
tags: [后端, 限流, 验证码]
date: 2026-10-06
updated: 2026-10-06
id: note-code-endpoint-ratelimit
---

# 验证码接口限流怎么做才不折腾正常用户

验证码接口是少数"每次调用都要花资源"的接口（要发邮件），也是最容易被拿来刷的接口。限流必须做，但做法讲究。

### 分三层限流

- **单邮箱冷却**：同一邮箱 60 秒内只能发一次。这是用户最能理解的一层，也是前端倒计时对应的规则。
- **单 IP 频次**：同一来源 10 分钟内最多 8 次，防止一个脚本换着邮箱刷。
- **全局开关**：发现异常时能一键关掉发信，避免把邮箱额度打光。

### 别只按 IP 限

公司、学校、手机运营商出口都是 NAT，一群人共用一个出口 IP。只按 IP 限会出现"别人刷爆了、我发不出去"的误伤。冷却按邮箱、频次按 IP，两层配合最稳。

### 冷却时间要"可反馈"

返回里带上还要等多少秒，前端就能把按钮变成倒计时，而不是让用户以为坏了：

```php
if ($wait > 0) {
    api_out(0, '发送太频繁，请 ' . $wait . ' 秒后再试', array('wait' => $wait));
}
```

### 先做人类验证，再发信

在"生成验证码 + 发邮件"之前插一道人机验证（图形验证码或行为验证），成本远低于发一封邮件。顺序很重要：验证 → 限流 → 发信。

### 错误信息别泄密

- 不要把 SMTP 原始应答、服务器路径回给前端
- 技术细节写进服务器日志，前台只给一句"请稍后重试"

### 最后

限流的目标不是"挡住所有人"，而是"让正常用户几乎无感，让脚本的成本高到不值得"。宁可阈值宽一点、层数多一点。
