Hotdry.

Article

curl 作为注册协议:无 UI 邮件代理网关的 OTP 验证设计

设计一种基于 curl 的邮件代理网关注册协议,通过人类可读 OTP 完成邮箱所有权验证,实现无界面、可脚本化的 API 访问授权流程。

2026-05-21web

在自动化运维和开发者工具链中,传统的 Web 注册流程往往成为效率瓶颈。用户需要打开浏览器、填写表单、点击验证链接,整个过程难以脚本化。本文探讨一种更直接的方案:将 curl 作为注册协议,通过邮件 OTP(一次性验证码)完成邮箱所有权验证,构建一个无 UI 的邮件代理网关。

核心设计思路

这个方案的核心假设是:邮箱地址本身就是一种去中心化的身份标识。如果用户能够接收并读取某个邮箱的邮件,就证明其对该邮箱拥有控制权。基于此,我们可以设计一个纯 HTTP 的注册流程:

  1. 用户通过 curl 向网关提交注册请求,携带目标邮箱地址
  2. 网关生成 OTP 并发送到该邮箱
  3. 用户从邮件客户端读取 OTP,再次通过 curl 提交验证
  4. 验证通过后,网关返回长期有效的 API 密钥

整个流程无需任何图形界面,完全可通过命令行和脚本完成。

协议端点设计

1. 注册请求端点

POST /v1/register
Content-Type: application/json

{
  "email": "user@example.com",
  "callback_url": "https://optional-hook.example.com"
}

网关收到请求后执行以下操作:

  • 生成 8 位数字 OTP(熵值约 26.6 bits,兼顾安全性与人工输入便利性)
  • 设置 OTP 有效期为 10 分钟
  • 向指定邮箱发送包含 OTP 的纯文本邮件
  • 返回注册会话 ID,用于后续验证关联

2. OTP 验证端点

POST /v1/verify
Content-Type: application/json

{
  "session_id": "reg_abc123xyz",
  "otp": "84729301"
}

验证成功后返回:

{
  "api_key": "ak_live_64char_random_string",
  "expires_at": "2027-05-22T07:25:03Z",
  "rate_limit": "1000/hour"
}

安全参数配置

在生产环境中,以下参数需要仔细调优:

OTP 生成策略

  • 长度:8 位数字(6 位易被暴力破解,10 位人工输入困难)
  • 字符集:纯数字,避免大小写混淆
  • 熵源:使用 crypto/rand 或 /dev/urandom,禁用伪随机数生成器

速率限制规则

  • 单邮箱:每 60 秒最多 1 次注册请求
  • 单 IP:每 5 分钟最多 3 次注册请求
  • OTP 验证:单会话最多 5 次尝试,超限则销毁会话

邮件发送策略

  • 使用延迟队列,避免被标记为垃圾邮件
  • 邮件主题包含明确标识,如 "[ServiceName] 验证码:84729301"
  • 正文仅包含必要信息,避免被邮件客户端截断

curl 命令示例

完整的注册流程可通过以下命令完成:

# 步骤 1:发起注册
SESSION=$(curl -s -X POST https://gateway.example.com/v1/register \
  -H "Content-Type: application/json" \
  -d '{"email":"user@example.com"}' \
  | jq -r '.session_id')

echo "OTP 已发送至邮箱,请查收后输入:"
read OTP

# 步骤 2:提交验证
curl -s -X POST https://gateway.example.com/v1/verify \
  -H "Content-Type: application/json" \
  -d "{\"session_id\":\"$SESSION\",\"otp\":\"$OTP\"}" \
  | jq -r '.api_key' > ~/.gateway_api_key

网关实现要点

会话存储

使用 Redis 存储临时注册会话,键结构如下:

reg:{session_id} -> {email, otp, attempts, created_at}
email:{email} -> {session_id, requested_at}  # 用于速率限制

设置 TTL 为 OTP 有效期 + 5 分钟缓冲,确保过期数据自动清理。

幂等性处理

同一邮箱在 OTP 有效期内重复注册时,应返回相同会话 ID 并重新发送 OTP(带冷却期),而非创建新会话。这防止用户因未收到邮件而重复注册导致会话混乱。

API 密钥管理

验证通过后生成的 API 密钥应遵循以下原则:

  • 使用 64 字节以上随机字符串(512 bits 熵值)
  • 存储哈希值(SHA-256)而非明文,验证时比对哈希
  • 支持密钥轮换,旧密钥在 24 小时宽限期后失效
  • 提供密钥撤销端点,供用户紧急停用

适用场景与局限

这种设计特别适合以下场景:

  • CI/CD 流水线需要动态获取 API 凭证
  • 命令行工具需要用户级授权但不想维护登录状态
  • 临时环境快速创建测试账号
  • 无浏览器环境(如服务器、容器内)的自动化操作

局限性包括:依赖外部邮件系统延迟(通常 1-30 秒),不适合需要即时反馈的交互场景;以及邮箱服务商可能对验证码邮件进行过滤,需要与主流邮箱进行兼容性测试。

监控与告警

生产部署时应关注以下指标:

  • OTP 发送成功率(目标 > 99%)
  • 验证成功率(正常用户应 > 95%,过低可能表示 UX 问题)
  • 平均验证完成时间(从发送到提交,正常用户通常在 2 分钟内)
  • 暴力尝试检测(单会话超过 3 次失败验证触发告警)

参考资料

  • MDN Web Docs: One-time passwords (OTP) - Security
  • Transmit Security: Verify email using OTP - Mosaic documentation
  • Authsignal: Email OTP - Universal Multi-Factor Authentication

web

内容声明:本文无广告投放、无付费植入。

如有事实性问题,欢迎发送勘误至 i@hotdrydog.com