API 测试指南
概述
本项目的 API 使用 API Key + HMAC-SHA256 签名认证方式。由于签名需要动态计算,本指南提供了多种测试方法。
推荐测试方式
方式一:签名生成工具(推荐)
最简单的方式是使用项目提供的签名生成工具:
# 生成 GET 请求签名
cd apps/api
pnpm sign GET /api/v1/intents
# 生成 POST 请求签名
pnpm sign POST /api/v1/intents '{"userId":"user123","platform":"TAOBAO",...}'工具会自动输出:
- 🔐 签名信息:时间戳、签名值、App ID
- 📋 curl 命令:可直接复制执行的完整命令
- 📝 请求头:Swagger/Postman 中手动填写用
方式二:使用 Postman
如果你想使用 HTTP 客户端工具,可以配置 Pre-request Script 来自动计算签名。
Postman Pre-request Script
在 Collection 或 Request 的 Pre-request Script 标签中添加:
// 从环境变量读取配置
const APP_ID = pm.environment.get("API_APP_ID") || "dev_app_local";
const SECRET = pm.environment.get("API_SECRET") || "dev_secret_local_do_not_use_in_production";
// 生成时间戳
const timestamp = Date.now().toString();
// 获取请求信息
const method = pm.request.method;
const url = new URL(pm.request.url.toString());
const path = url.pathname + url.search;
// 获取请求体
let body = "";
if (pm.request.body && pm.request.body.mode === "raw") {
body = pm.request.body.raw;
}
// 构建签名载荷
const payload = method + path + timestamp + body;
// 计算签名
const signature = CryptoJS.HmacSHA256(payload, SECRET).toString();
// 设置请求头
pm.request.headers.add({
key: "X-App-Id",
value: APP_ID
});
pm.request.headers.add({
key: "X-Timestamp",
value: timestamp
});
pm.request.headers.add({
key: "X-Signature",
value: signature
});
console.log("🔐 Request signed:", {
method,
path,
appId: APP_ID,
timestamp,
signature: signature.substring(0, 16) + "..."
});配置 Postman 环境变量
- 在 Postman 中创建新环境
- 添加以下变量:
API_APP_ID:dev_app_localAPI_SECRET:dev_secret_local_do_not_use_in_productionAPI_BASE_URL:http://localhost:3001
使用步骤
- 选择创建的环境
- 发送请求前,Pre-request Script 会自动计算签名
- 查看 Console 可以看到签名详情
方式三:使用 curl
如果你想用 curl 测试,需要手动计算签名:
# 设置变量
APP_ID="dev_app_local"
SECRET="dev_secret_local_do_not_use_in_production"
METHOD="GET"
PATH="/api/v1/intents"
TIMESTAMP=$(date +%s000)
BODY=""
# 计算签名
PAYLOAD="${METHOD}${PATH}${TIMESTAMP}${BODY}"
SIGNATURE=$(echo -n "$PAYLOAD" | openssl dgst -sha256 -hmac "$SECRET" | awk '{print $2}')
# 发送请求
curl -X GET "http://localhost:3001/api/v1/intents" \
-H "Content-Type: application/json" \
-H "X-App-Id: $APP_ID" \
-H "X-Timestamp: $TIMESTAMP" \
-H "X-Signature: $SIGNATURE"POST 请求示例
# 设置变量
APP_ID="dev_app_local"
SECRET="dev_secret_local_do_not_use_in_production"
METHOD="POST"
PATH="/api/v1/intents"
TIMESTAMP=$(date +%s000)
BODY='{"userId":"user123","platform":"TAOBAO","productUrl":"https://item.taobao.com/item.htm?id=123456","title":"测试商品","price":99.9,"quantity":1,"recipientName":"张三","address":"北京市朝阳区","phone":"13800138000"}'
# 计算签名
PAYLOAD="${METHOD}${PATH}${TIMESTAMP}${BODY}"
SIGNATURE=$(echo -n "$PAYLOAD" | openssl dgst -sha256 -hmac "$SECRET" | awk '{print $2}')
# 发送请求
curl -X POST "http://localhost:3001/api/v1/intents" \
-H "Content-Type: application/json" \
-H "X-App-Id: $APP_ID" \
-H "X-Timestamp: $TIMESTAMP" \
-H "X-Signature: $SIGNATURE" \
-d "$BODY"Swagger UI 使用说明
⚠️ 限制说明
Swagger UI 目前不支持自动计算签名。原因是:
- 动态时间戳:每次请求都不同
- 请求体内容:签名包含完整的请求体
- 请求路径:签名包含完整的 URL 路径和参数
Swagger UI 的认证机制设计为静态 token,不支持这种复杂的动态签名计算。
手动使用 Swagger
如果你仍然想使用 Swagger UI,需要手动填写:
- 访问:http://localhost:3001/openapi
- 点击右上角 🔓 Authorize 按钮
- 在弹出的对话框中填写三个认证头:
- X-App-Id:
dev_app_local - X-Timestamp: 当前时间戳(毫秒),例如
1708547123456 - X-Signature: 使用上述方式计算的签名
- X-App-Id:
警告: 由于时间戳有 5 分钟的有效期,手动填写的签名会很快过期。强烈建议使用自动化测试脚本或 Postman。
本地开发凭证
默认的开发环境凭证(已在 .env 文件中配置):
API_APP_ID=dev_app_local
API_SECRET=dev_secret_local_do_not_use_in_production警告: 这些凭证仅用于本地开发,绝不可用于生产环境!
常见问题
Q: 为什么我总是收到 401 Unauthorized?
A: 请检查:
- 时间戳是否是毫秒(13位数字)
- 签名计算是否正确(载荷格式:
METHOD + PATH + TIMESTAMP + BODY) - 时间差是否在 5 分钟内(客户端与服务器时间)
Q: 如何验证签名是否正确?
A: 使用测试脚本:
node apps/api/test-auth.js如果脚本成功,说明签名逻辑正确。然后对比脚本的签名计算方式。
Q: 可以禁用认证吗?
A: 健康检查接口 GET / 已经禁用了认证。如果需要为其他接口禁用认证,在 Controller 方法上添加 @Public() 装饰器。
Q: 如何查看签名计算过程?
A: 查看 API 鉴权文档 中的详细示例,或者运行测试脚本并查看其源代码。
Q: Postman 报错 “CryptoJS is not defined”
A: Postman 内置了 CryptoJS 库。如果报错,请确保:
- 使用的是 Postman 桌面版(不是 Web 版)
- Pre-request Script 放在正确的位置
- 尝试重启 Postman
Q: 如何测试不同的环境?
A: 在 Postman 中:
- 创建多个环境(开发、测试、生产)
- 为每个环境配置不同的
API_APP_ID、API_SECRET和API_BASE_URL - 切换环境即可测试不同的服务器
生产环境测试
生产环境必须使用强密钥:
# 生成强密钥(至少32字符)
export API_APP_ID="production_app_id_$(openssl rand -hex 8)"
export API_SECRET="$(openssl rand -hex 32)"警告: 生产环境密钥要求:
- 使用强随机生成器
- 至少 32 字符长度
- 定期轮换密钥
- 使用密钥管理服务(如 AWS Secrets Manager、HashiCorp Vault)
测试清单
使用以下清单确保 API 正常工作:
- 健康检查接口可以访问(无需认证)
- 创建意图接口返回 201 Created
- 查询意图列表返回数组
- 查询单个意图返回详情
- 更新意图成功
- 取消意图成功
- 删除意图返回 204 No Content
- 无效签名返回 401 Unauthorized
- 过期时间戳返回 401 Unauthorized
- 缺少必填字段返回 400 Bad Request