这是 Beta 探索课程,内容结构、实验步骤和示例可能会继续调整。
滥用问题
场景
我的 API 平台越来越受欢迎。
两个月后,我去看了监控数据:
那时候的我还不明白,危险正在逼近。
异常发现
某天早上,我收到了外部 API 提供商的邮件:
Inbox
From: 外部 API 提供商
To: 我
Time: 周三 09:15
Subject: 【重要通知】调用配额异常
我们检测到您的 API 调用异常:
- 昨天:00:00-06:00,调用量异常
- 6 小时内调用了:8000 次
- 正常情况:全天约 5000 次
请检查是否有异常调用。
如继续异常,我们将暂停服务。
看到邮件的那一刻,我后背发凉:6 小时调用了 8000 次?
这意味着有人在 24 小时内可以消耗我 32000 次配额,而我的免费额度只有 10000 次/天。
调查过程
我赶紧查看日志,结果让我震惊:
Top 10 IP:
203.0.113.1: 7500 次 ← 异常!
198.51.100.1: 150 次
198.51.100.2: 120 次
...发现异常 IP:203.0.113.1
深入分析
我查看了这个 IP 的调用日志:
access.log
$ grep "203.0.113.1" access.log | tail -20 10:00:01 GET /api/weather?city=北京 10:00:01 GET /api/weather?city=上海 10:00:02 GET /api/weather?city=深圳 10:00:02 GET /api/weather?city=广州 10:00:03 GET /api/weather?city=杭州 10:00:03 GET /api/weather?city=南京
特征:
- 每秒调用 2-3 次
- 轮流查询不同城市
- 持续不断,没有停止
结论:有人在爬取数据!
问题严重性
我计算了一下:
这个爬虫的调用情况:
- 每秒:2-3 次
- 每分钟:约 150 次
- 每小时:约 9000 次
- 每天:约 216000 次
占用的外部 API 配额:
- 我的限额:10000 次/天
- 这个爬虫:216000 次/天
- 影响:会让我的账号被限流!更糟糕的是:
- 正常用户无法访问(外部 API 限流)
- 我的服务不可用
- 用户开始投诉
那一刻,我真的慌了。
尝试解决
方案 1:封禁 IP
我先把异常 IP 封禁了:
设计流程
方案 1:封禁 IP
- 步骤 1:校验调用方身份,并绑定用户、应用和权限范围
- 步骤 2:读取 API Key、调用方信息和请求上下文
- 步骤 3:根据认证结果、权限和配额决定放行或拒绝
- 步骤 4:返回认证结果,并写入审计、配额和异常访问记录
关注点:身份可信度、权限边界、配额消耗和审计追踪。
效果:
- 这个爬虫被阻止了
- 但几天后,又出现了新的爬虫 IP
我知道,这是场猫鼠游戏,我追不上。
方案 2:限制单个 IP 的调用频率
设计流程
方案 2:限制单个 IP 的调用频率
- 步骤 1:校验调用方身份,并绑定用户、应用和权限范围
- 步骤 2:读取 API Key、调用方信息和请求上下文
- 步骤 3:根据认证结果、权限和配额决定放行或拒绝
- 步骤 4:返回认证结果,并写入审计、配额和异常访问记录
关注点:身份可信度、权限边界、配额消耗和审计追踪。
效果:
- 限制了单个 IP 的调用频率 ✅
- 但如果有人用很多个 IP 呢?❌
- IP 记录越来越多,内存占用增加 ❌
这个方案还是治标不治本。
方案 3:关键问题
那天晚上我在想:为什么任何人都能随意调用我的 API?
问题在于:没有门槛。
我需要一种机制来:
- 识别谁在调用
- 限制每个用户的调用配额
- 防止滥用
解决思路
我需要引入用户认证系统。
核心概念:
每个用户注册 → 获得唯一的 API Key
每次调用 → 必须携带 API Key
根据 API Key → 识别用户身份、限制配额┌─────────────┐
│ 开发者 │
└──────┬──────┘
│
│ 1. 注册
▼
┌─────────────────────┐
│ 我的平台 │
│ - 分配 API Key │
│ - 设置调用配额 │
└──────┬──────────────┘
│
│ 2. 调用 API (携带 API Key)
▼
┌─────────────────────┐
│ 验证 API Key │
│ - 检查是否有效 │
│ - 检查配额 │
└──────┬──────────────┘
│
│ 3. 返回数据
▼
┌─────────────┐
│ 成功/失败 │
└─────────────┘这是最彻底,但也最复杂的方案。
作为 solo founder,我的时间有限。但我明白,有些路再难走也要走。
我决定:干。