API接口被刷怎么办_PHP高并发接口防护方法汇总【解答】

1次阅读

api防护需分层拦截、精准识别、快速响应:redis毫秒级限流须按ip+路径组合并原子操作;高危接口叠加user_id/device_id;签名须字典序拼接、timestamp≤30秒、nonce防复用;验证码仅用于高危操作且服务端校验后立即销毁;日志监控需记录限流详情并设关键词告警。

API接口被刷怎么办_PHP高并发接口防护方法汇总【解答】

API 接口被刷,不是“会不会发生”的问题,而是“什么时候开始、刷到什么程度才崩”的问题。单纯靠加个 if ($ip_count > 100) 拦不住真实攻击,也拦不住合法用户多端并发——真正有效的防护,是分层拦截 + 精准识别 + 快速响应。

用 Redis 实现毫秒级 IP 限流,但别只 count++

现象:刚加完 $redis->incr($ip),发现攻击者换代理就绕过;或者内部系统调用也被误杀。

原因在于没做维度隔离和时间窗口对齐——IP 是最粗的粒度,必须叠加更多上下文。

  • IP + 接口路径 组合限流,避免 /login 被刷影响 /public/info
  • INCR + EXPIRE 原子操作替代先 GET 再 SET,防止并发漏计数:
    $key = "rate:{$ip}:{$path}";$redis->eval("return redis.call('INCR', KEYS[1]) * redis.call('EXPIRE', KEYS[1], ARGV[1])", 1, $key, 60);
  • 对登录、短信等高风险接口,额外加 user_iddevice_id 维度,防账号爆破

签名验证不是加个 sha1($secret . $data) 就安全

现象:签名校验通过,但请求参数被重放或篡改;或者服务端验签失败,客户端却说“我明明按文档写的”。

立即学习PHP免费学习笔记(深入)”;

问题出在签名构造规则不一致、时间窗太宽、nonce 复用没防控。

  • 参数必须按字典序(ASCII)排序后拼接,不能靠 json_encode() —— 它不保证键序,且空格/换行不可控
  • timestamp 有效期建议 ≤ 30 秒,超时直接拒收,避免重放攻击
  • nonce 要存 Redis 并设 TTL(如 5 分钟),且必须用 SETNX + EXPIRE 原子写入,否则并发下可能漏判
  • 密钥 $secret_key 别硬编码,应从环境变量或配置中心加载,禁止提交到 git

别让验证码成为性能瓶颈,也别让它形同虚设

现象:加了验证码后,接口 QPS 断崖下跌;或者验证码图片能被 ocr 自动识别,防护等于没做。

验证码本质是人机区分手段,不是所有接口都该上,更不该用错位置。

  • 仅对高危操作启用:如登录、注册、密码重置、短信发送,不要放在通用数据查询接口上
  • 服务端生成时,把答案存 Redis 并绑定 session_id 或临时 Token,过期时间 ≤ 5 分钟
  • 避免使用易识别的数字+字母组合(如 123abc),推荐带干扰线+轻微扭曲的图形验证码,或更现代的 hCaptcha / reCAPTCHA v3(后端只验 token)
  • 前端提交验证码时,必须携带对应 captcha_token,服务端比对后立即 DEL,杜绝重放

日志和监控不是上线后才配,而是限流逻辑的一部分

现象:被刷了才发现,查日志要翻半小时;或者告警阈值设成“CPU > 90%”,等收到邮件时服务已瘫痪。

防御失效的第一现场永远在日志里,但没人看的日志等于没记。

  • 记录被限流的请求:IP、路径、timestamp、触发的规则名(如 ip_path_60s_10),写入独立 access_rate.log
  • Monolog 配合 syslogelk,设置关键词告警:“Too many requests”、“Invalid signature”、“Captcha mismatch”
  • Redis 中限流 key 的命中率、过期率、平均 TTL 剩余时间,都是关键指标——它们比服务器 CPU 更早暴露攻击模式
  • 定期跑脚本清理长期未更新的 nonce 和验证码缓存,避免 Redis 内存缓慢泄漏

真正难的不是写几行限流代码,而是判断哪个接口该用哪一层防护、每层之间怎么协同不打架、以及当某条规则突然开始高频触发时,你能不能 5 分钟内定位是业务变更还是攻击升级。这些细节不会出现在框架文档里,但决定了你的 API 是扛住百万请求,还是在凌晨三点被一个 Python 脚本干趴。

text=ZqhQzanResources