23 KiB
Top-Fans Backend HTTP 完整测试流程
本文档提供所有已实现接口的完整 HTTP 测试流程,按照真实使用场景组织。
📋 目录
前置准备
1. 启动服务
# 终端 1: 启动 userService
cd /Users/haihuizhu/infinite_matrix/top-fans/backend/services/userService
go run main.go
# 终端 2: 启动 Gateway
cd /Users/haihuizhu/infinite_matrix/top-fans/backend/gateway
go run main.go
2. 验证服务运行
# 检查 Dubbo 服务(端口 20000)
lsof -i :20000
# 检查 Gateway(端口 8080)
lsof -i :8080
# 测试 Gateway 健康检查
curl http://localhost:8080/health
3. 准备测试数据
确保数据库中有以下 stars 数据:
-- 肖战(identity_id: xz)
INSERT INTO stars (star_id, name, tag, name_en, pic_url, description, identity_id, is_active, created_at, updated_at)
VALUES (87, '肖战', '小飞侠', 'xiaozhan', '', '', 'xz', true, 1767590443835, 1767590443835);
-- 王一博(identity_id: wyb)
INSERT INTO stars (star_id, name, tag, name_en, pic_url, description, identity_id, is_active, created_at, updated_at)
VALUES (88, '王一博', '小摩托', 'wangyibo', '', '', 'wyb', true, 1767590443835, 1767590443835);
4. 环境变量
export BASE_URL="http://localhost:8080"
export API_VERSION="v1"
测试场景1:新用户注册与认证
1.1 查看可选粉丝身份列表
目的:用户注册前,先查看有哪些明星可以选择。
curl -X GET "${BASE_URL}/api/${API_VERSION}/fan-identities" | jq .
预期响应:
{
"code": 200,
"message": "ok",
"data": {
"items": [
{
"star_id": 87,
"identity_id": "xz",
"name": "肖战",
"tag": "小飞侠",
"pic_url": ""
},
{
"star_id": 88,
"identity_id": "wyb",
"name": "王一博",
"tag": "小摩托",
"pic_url": ""
}
],
"total": 2
}
}
1.2 用户注册
目的:新用户注册并选择初始粉丝身份。
curl -X POST "${BASE_URL}/api/${API_VERSION}/auth/register" \
-H "Content-Type: application/json" \
-d '{
"mobile": "13900000001",
"password": "password123",
"star_id": 87,
"nickname": "不爱战战"
}' | jq .
预期响应:
{
"code": 200,
"message": "ok",
"data": {
"access_token": "eyJhbGci...",
"expires_in": 604800,
"user": {
"uid": 1,
"nickname": "爱战战",
"avatar_url": "",
"chain_address": "",
"fan_identity": {
"identity_id": "xz",
"name": "肖战",
"tag": "小飞侠"
},
"fan_level": 1,
"starbook_limit": 1,
"slot_limit": 1,
"assets_count": 0,
"crystal_balance": 0
}
}
}
重要:保存返回的 access_token,后续请求需要用到。
# 保存 Token 到环境变量(替换为实际返回的 token)
export TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxMDYsInN0YXJfaWQiOjg3LCJ1cGRhdGVkX2F0IjoxNzY3Njg5NzI0NTU1LCJleHAiOjE3NjgyOTQ1MjQsImlhdCI6MTc2NzY4OTcyNH0.emLob9wybZgqU7O5j-mOzBJQTm-Bvz-iaBu8Nb3wr_Q"
1.3 获取当前用户信息
目的:验证注册成功,获取完整用户信息。
curl -X GET "${BASE_URL}/api/${API_VERSION}/auth/me" \
-H "Authorization: Bearer ${TOKEN}" | jq .
预期响应:
{
"code": 200,
"message": "ok",
"data": {
"uid": 1,
"nickname": "爱战战",
"avatar_url": "",
"chain_address": "",
"current_identity": {
"identity_id": "xz",
"identity_name": "肖战",
"tag": "小飞侠",
"level": 1,
"crystal_balance": 0
}
}
}
测试场景2:用户登录与个人信息管理
2.1 用户登录
目的:已注册用户使用手机号和密码登录。
基本登录(使用默认身份):
curl -X POST "${BASE_URL}/api/${API_VERSION}/auth/login" \
-H "Content-Type: application/json" \
-d '{
"mobile": "13900000001",
"password": "password123"
}' | jq .
指定明星身份登录:
curl -X POST "${BASE_URL}/api/${API_VERSION}/auth/login" \
-H "Content-Type: application/json" \
-d '{
"mobile": "13900000001",
"password": "password123",
"star_id": 87
}' | jq .
请求参数说明:
mobile(必填): 手机号password(必填): 密码star_id(可选): 指定登录的明星ID- 不指定:使用最早创建的粉丝档案(默认行为)
- 指定:切换到指定明星的粉丝身份,前提是用户已创建该明星的粉丝档案
预期响应:
{
"code": 200,
"message": "ok",
"data": {
"access_token": "eyJhbGci...",
"expires_in": 604800,
"user": {
"uid": 1,
"nickname": "爱战战",
"avatar_url": "",
"chain_address": "",
"fan_identity": {
"identity_id": "xz",
"name": "肖战",
"tag": "小飞侠"
},
"fan_level": 1,
"starbook_limit": 1,
"slot_limit": 1,
"assets_count": 0,
"crystal_balance": 0
}
}
}
更新 Token:
export TOKEN="<新的 access_token>"
2.2 获取个人信息
目的:查看当前粉丝身份下的详细个人信息。
curl -X GET "${BASE_URL}/api/${API_VERSION}/me/profile" \
-H "Authorization: Bearer ${TOKEN}" | jq .
预期响应:
{
"code": 200,
"message": "ok",
"data": {
"uid": 1,
"nickname": "爱战战",
"chain_address": "",
"fan_identity": {
"identity_id": "xz",
"name": "肖战",
"tag": "小飞侠"
},
"fan_level": 1,
"starbook_limit": 1,
"slot_limit": 1,
"assets_count": 0,
"crystal_balance": 0
}
}
2.3 修改昵称
目的:用户修改自己的昵称。
curl -X PUT "${BASE_URL}/api/${API_VERSION}/me/nickname" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${TOKEN}" \
-d '{
"nickname": "爱战战的小飞侠"
}' | jq .
预期响应:
{
"code": 200,
"message": "ok",
"data": {
"nickname": "爱战战的小飞侠"
}
}
验证修改:
curl -X GET "${BASE_URL}/api/${API_VERSION}/me/profile" \
-H "Authorization: Bearer ${TOKEN}" | jq .data.nickname
预期输出:"爱战战的小飞侠"
测试场景3:粉丝身份管理
3.1 添加第二个粉丝身份
目的:用户添加第二个粉丝身份(最多2个)。
curl -X POST "${BASE_URL}/api/${API_VERSION}/my/fan-identities" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${TOKEN}" \
-d '{
"star_id": 88,
"nickname": "爱一博"
}' | jq .
预期响应:
{
"code": 200,
"message": "ok",
"data": {
"bound": true,
"identity_id": "wyb"
}
}
3.2 查询我的粉丝身份列表
目的:查询当前用户拥有的所有粉丝身份。
注意:请确保URL中没有多余的斜杠,正确的路径是 /api/v1/my/fan-identities(不是 /api/v1//my/fan-identities)
# 方式一:使用变量(推荐)
curl -X GET "${BASE_URL}/api/${API_VERSION}/my/fan-identities" \
-H "Authorization: Bearer ${TOKEN}" | jq .
# 方式二:直接使用完整URL
curl -X GET "http://localhost:8080/api/v1/my/fan-identities" \
-H "Authorization: Bearer ${TOKEN}" | jq .
预期响应:
{
"code": 200,
"message": "ok",
"data": {
"items": [
{
"star_id": 87,
"identity_id": "xz",
"star_name": "肖战",
"star_tag": "小飞侠",
"nickname": "小飞侠战战",
"level": 1,
"experience": 0,
"crystal_balance": 0,
"is_active": true
},
{
"star_id": 88,
"identity_id": "wyb",
"star_name": "王一博",
"star_tag": "小摩托",
"nickname": "爱一博",
"level": 1,
"experience": 0,
"crystal_balance": 0,
"is_active": false
}
],
"total": 2,
"current_star_id": 87
}
}
验证要点:
- ✅ 返回用户拥有的所有粉丝身份
- ✅
identity_id、star_name、star_tag正确显示明星信息(如 "xz"、"肖战"、"小飞侠") - ✅
is_active为true表示当前激活的身份(与current_star_id对应) - ✅
current_star_id显示当前激活的明星ID(从 Token 中获取) - ✅ 每个身份包含昵称、等级、经验值、水晶余额等完整信息
- ✅ 如果用户有2个粉丝身份,应该返回2条记录
3.4 查看可选身份列表(搜索功能)
目的:测试身份列表的搜索功能。
# 搜索"王一博"
curl -X GET "${BASE_URL}/api/${API_VERSION}/fan-identities?keyword=王一博" | jq .
# 搜索"肖战"
curl -X GET "${BASE_URL}/api/${API_VERSION}/fan-identities?keyword=肖战" | jq .
# 分页查询
curl -X GET "${BASE_URL}/api/${API_VERSION}/fan-identities?page=1&page_size=10" | jq .
3.5 切换粉丝身份
目的:切换到另一个粉丝身份,系统会返回新的 Token。
curl -X POST "${BASE_URL}/api/${API_VERSION}/my/fan-identities/switch" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${TOKEN}" \
-d '{
"new_star_id": 88
}' | jq .
预期响应:
{
"code": 200,
"message": "ok",
"data": {
"access_token": "eyJhbGci...",
"expires_in": 604800,
"current_identity": {
"identity_id": "wyb",
"identity_name": "王一博",
"tag": "小摩托",
"level": 1,
"crystal_balance": 0
}
}
}
重要:切换身份后会返回新的 Token,必须更新。
export TOKEN="<新的 access_token>"
验证切换结果:
curl -X GET "${BASE_URL}/api/${API_VERSION}/auth/me" \
-H "Authorization: Bearer ${TOKEN}" | jq .data.current_identity
预期输出:
{
"identity_id": "wyb",
"identity_name": "王一博",
"tag": "小摩托",
"level": 1,
"crystal_balance": 0
}
3.4 再次切换回第一个身份
curl -X POST "${BASE_URL}/api/${API_VERSION}/my/fan-identities/switch" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${TOKEN}" \
-d '{
"new_star_id": 87
}' | jq .
更新 Token 并验证。
测试场景4:账户安全
4.1 修改密码
目的:用户修改登录密码,修改后当前 Token 会失效。
curl -X POST "${BASE_URL}/api/${API_VERSION}/account/password" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${TOKEN}" \
-d '{
"old_password": "password123",
"new_password": "newPassword456"
}' | jq .
预期响应:
{
"code": 200,
"message": "ok",
"data": {}
}
4.2 验证旧 Token 失效
目的:确认修改密码后,旧 Token 立即失效。
curl -X GET "${BASE_URL}/api/${API_VERSION}/auth/me" \
-H "Authorization: Bearer ${TOKEN}" | jq .
预期响应:
{
"code": 401,
"message": "token已失效或不存在"
}
4.3 使用新密码重新登录
curl -X POST "${BASE_URL}/api/${API_VERSION}/auth/login" \
-H "Content-Type: application/json" \
-d '{
"mobile": "13800000001",
"password": "newPassword456"
}' | jq .
预期:登录成功,获取新 Token。
export TOKEN="<新的 access_token>"
4.4 退出登录
目的:用户主动退出登录,Token 会被清除。
curl -X POST "${BASE_URL}/api/${API_VERSION}/auth/logout" \
-H "Authorization: Bearer ${TOKEN}" | jq .
预期响应:
{
"code": 200,
"message": "ok",
"data": {}
}
验证退出成功:
curl -X GET "${BASE_URL}/api/${API_VERSION}/auth/me" \
-H "Authorization: Bearer ${TOKEN}" | jq .
预期响应:401 未授权。
错误场景测试
5.1 重复注册(手机号已存在)
curl -X POST "${BASE_URL}/api/${API_VERSION}/auth/register" \
-H "Content-Type: application/json" \
-d '{
"mobile": "13800000001",
"password": "password123",
"star_id": 87,
"nickname": "重复用户"
}' | jq .
预期响应:
{
"code": 400,
"message": "手机号已存在"
}
5.2 登录密码错误
curl -X POST "${BASE_URL}/api/${API_VERSION}/auth/login" \
-H "Content-Type: application/json" \
-d '{
"mobile": "13800000001",
"password": "wrongPassword"
}' | jq .
预期响应:
{
"code": 401,
"message": "密码错误"
}
5.3 使用无效 Token 访问受保护接口
curl -X GET "${BASE_URL}/api/${API_VERSION}/auth/me" \
-H "Authorization: Bearer invalid_token" | jq .
预期响应:
{
"code": 401,
"message": "invalid token"
}
5.4 缺少 Authorization Header
curl -X GET "${BASE_URL}/api/${API_VERSION}/auth/me" | jq .
预期响应:
{
"code": 401,
"message": "missing authorization token"
}
5.5 添加第三个粉丝身份(超过限制)
# 先注册一个新用户
curl -X POST "${BASE_URL}/api/${API_VERSION}/auth/register" \
-H "Content-Type: application/json" \
-d '{
"mobile": "13800000002",
"password": "password123",
"star_id": 87,
"nickname": "测试用户2"
}' | jq .
# 保存新 Token
export TOKEN2="<新用户的 token>"
# 添加第二个身份
curl -X POST "${BASE_URL}/api/${API_VERSION}/my/fan-identities" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${TOKEN2}" \
-d '{
"star_id": 88,
"nickname": "第二个身份"
}' | jq .
# 尝试添加第三个身份(应该失败)
curl -X POST "${BASE_URL}/api/${API_VERSION}/my/fan-identities" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${TOKEN2}" \
-d '{
"star_id": 89,
"nickname": "第三个身份"
}' | jq .
预期响应:
{
"code": 400,
"message": "最多只能拥有2个粉丝身份"
}
5.6 修改密码时旧密码错误
curl -X POST "${BASE_URL}/api/${API_VERSION}/account/password" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${TOKEN}" \
-d '{
"old_password": "wrongOldPassword",
"new_password": "newPassword456"
}' | jq .
预期响应:
{
"code": 400,
"message": "旧密码错误"
}
5.7 切换到不存在的身份
curl -X POST "${BASE_URL}/api/${API_VERSION}/my/fan-identities/switch" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${TOKEN}" \
-d '{
"new_star_id": 999
}' | jq .
预期响应:
{
"code": 404,
"message": "粉丝档案不存在"
}
接口清单
✅ 已实现的接口(共10个)
认证相关(5个)
| 方法 | 路径 | 说明 | 需要认证 |
|---|---|---|---|
| POST | /api/v1/auth/register |
用户注册 | ❌ |
| POST | /api/v1/auth/login |
用户登录 | ❌ |
| GET | /api/v1/auth/me |
获取当前用户 | ✅ |
| POST | /api/v1/auth/logout |
退出登录 | ✅ |
| POST | /api/v1/account/password |
修改密码 | ✅ |
粉丝身份相关(3个)
| 方法 | 路径 | 说明 | 需要认证 |
|---|---|---|---|
| GET | /api/v1/fan-identities |
获取粉丝身份列表 | ❌ |
| POST | /api/v1/my/fan-identities |
添加粉丝身份 | ✅ |
| POST | /api/v1/my/fan-identities/switch |
切换粉丝身份 | ✅ |
个人信息相关(2个)
| 方法 | 路径 | 说明 | 需要认证 |
|---|---|---|---|
| GET | /api/v1/me/profile |
获取个人信息 | ✅ |
| PUT | /api/v1/me/nickname |
修改昵称 | ✅ |
完整测试脚本
将以下脚本保存为 test_all.sh,一键运行所有测试:
#!/bin/bash
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 配置
BASE_URL="http://localhost:8080"
API_VERSION="v1"
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN} Top-Fans Backend 完整测试流程${NC}"
echo -e "${GREEN}========================================${NC}\n"
# 1. 查看粉丝身份列表
echo -e "${YELLOW}[测试 1/10] 查看粉丝身份列表${NC}"
curl -s -X GET "${BASE_URL}/api/${API_VERSION}/fan-identities" | jq .
echo -e "\n"
# 2. 注册新用户
echo -e "${YELLOW}[测试 2/10] 注册新用户${NC}"
REGISTER_RESPONSE=$(curl -s -X POST "${BASE_URL}/api/${API_VERSION}/auth/register" \
-H "Content-Type: application/json" \
-d '{
"mobile": "13900000001",
"password": "password123",
"star_id": 87,
"nickname": "测试用户"
}')
echo "$REGISTER_RESPONSE" | jq .
TOKEN=$(echo "$REGISTER_RESPONSE" | jq -r '.data.access_token')
echo -e "${GREEN}Token: ${TOKEN}${NC}\n"
# 3. 获取当前用户
echo -e "${YELLOW}[测试 3/10] 获取当前用户${NC}"
curl -s -X GET "${BASE_URL}/api/${API_VERSION}/auth/me" \
-H "Authorization: Bearer ${TOKEN}" | jq .
echo -e "\n"
# 4. 获取个人信息
echo -e "${YELLOW}[测试 4/10] 获取个人信息${NC}"
curl -s -X GET "${BASE_URL}/api/${API_VERSION}/me/profile" \
-H "Authorization: Bearer ${TOKEN}" | jq .
echo -e "\n"
# 5. 修改昵称
echo -e "${YELLOW}[测试 5/10] 修改昵称${NC}"
curl -s -X PUT "${BASE_URL}/api/${API_VERSION}/me/nickname" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${TOKEN}" \
-d '{
"nickname": "新昵称测试"
}' | jq .
echo -e "\n"
# 6. 添加第二个粉丝身份
echo -e "${YELLOW}[测试 6/10] 添加第二个粉丝身份${NC}"
curl -s -X POST "${BASE_URL}/api/${API_VERSION}/my/fan-identities" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${TOKEN}" \
-d '{
"star_id": 88,
"nickname": "第二个身份"
}' | jq .
echo -e "\n"
# 7. 切换粉丝身份
echo -e "${YELLOW}[测试 7/10] 切换粉丝身份${NC}"
SWITCH_RESPONSE=$(curl -s -X POST "${BASE_URL}/api/${API_VERSION}/my/fan-identities/switch" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${TOKEN}" \
-d '{
"new_star_id": 88
}')
echo "$SWITCH_RESPONSE" | jq .
TOKEN=$(echo "$SWITCH_RESPONSE" | jq -r '.data.access_token')
echo -e "${GREEN}新 Token: ${TOKEN}${NC}\n"
# 8. 验证切换结果
echo -e "${YELLOW}[测试 8/10] 验证切换结果${NC}"
curl -s -X GET "${BASE_URL}/api/${API_VERSION}/auth/me" \
-H "Authorization: Bearer ${TOKEN}" | jq .data.current_identity
echo -e "\n"
# 9. 修改密码
echo -e "${YELLOW}[测试 9/10] 修改密码${NC}"
curl -s -X POST "${BASE_URL}/api/${API_VERSION}/account/password" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${TOKEN}" \
-d '{
"old_password": "password123",
"new_password": "newPassword456"
}' | jq .
echo -e "\n"
# 10. 使用新密码登录
echo -e "${YELLOW}[测试 10/10] 使用新密码登录${NC}"
LOGIN_RESPONSE=$(curl -s -X POST "${BASE_URL}/api/${API_VERSION}/auth/login" \
-H "Content-Type: application/json" \
-d '{
"mobile": "13900000001",
"password": "newPassword456"
}')
echo "$LOGIN_RESPONSE" | jq .
TOKEN=$(echo "$LOGIN_RESPONSE" | jq -r '.data.access_token')
echo -e "\n"
# 11. 退出登录
echo -e "${YELLOW}[额外测试] 退出登录${NC}"
curl -s -X POST "${BASE_URL}/api/${API_VERSION}/auth/logout" \
-H "Authorization: Bearer ${TOKEN}" | jq .
echo -e "\n"
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN} 测试完成!${NC}"
echo -e "${GREEN}========================================${NC}"
运行脚本:
chmod +x test_all.sh
./test_all.sh
性能测试(可选)
使用 apache-bench 进行简单的性能测试:
# 安装 apache-bench(如果未安装)
# macOS: brew install httpd
# Ubuntu: sudo apt-get install apache2-utils
# 测试登录接口(100个请求,10个并发)
ab -n 100 -c 10 -p login.json -T application/json \
http://localhost:8080/api/v1/auth/login
# login.json 内容:
# {"mobile":"13800000001","password":"password123"}
故障排查
问题1:401 Unauthorized
可能原因:
- Token 过期
- Token 格式错误(缺少 "Bearer " 前缀)
- 修改密码或退出登录后 Token 失效
解决方案:
# 检查 Token 格式
echo "Authorization: Bearer ${TOKEN}"
# 重新登录获取新 Token
curl -X POST "${BASE_URL}/api/${API_VERSION}/auth/login" \
-H "Content-Type: application/json" \
-d '{"mobile":"13800000001","password":"password123"}'
问题2:Connection Refused
可能原因:服务未启动
解决方案:
# 检查服务状态
lsof -i :20000 # Dubbo 服务
lsof -i :8080 # Gateway
# 重新启动服务
cd /Users/haihuizhu/infinite_matrix/top-fans/backend/services/userService
go run main.go
cd /Users/haihuizhu/infinite_matrix/top-fans/backend/gateway
go run main.go
问题3:数据库连接错误
检查数据库连接:
psql -h localhost -U haihuizhu -d top-fans -c "SELECT * FROM stars;"
附录
A. 快速参考
# 设置环境变量
export BASE_URL="http://localhost:8080"
export API_VERSION="v1"
export TOKEN="your_token_here"
# 常用命令
# 注册
curl -X POST "${BASE_URL}/api/${API_VERSION}/auth/register" -H "Content-Type: application/json" -d '{"mobile":"13800000001","password":"password123","star_id":87,"nickname":"测试"}'
# 登录
curl -X POST "${BASE_URL}/api/${API_VERSION}/auth/login" -H "Content-Type: application/json" -d '{"mobile":"13800000001","password":"password123"}'
# 获取当前用户
curl -X GET "${BASE_URL}/api/${API_VERSION}/auth/me" -H "Authorization: Bearer ${TOKEN}"
# 退出登录
curl -X POST "${BASE_URL}/api/${API_VERSION}/auth/logout" -H "Authorization: Bearer ${TOKEN}"
B. 响应码说明
| 状态码 | 说明 |
|---|---|
| 200 | 成功 |
| 400 | 请求参数错误 |
| 401 | 未授权(Token 无效或过期) |
| 404 | 资源不存在 |
| 500 | 服务器内部错误 |
总结
✅ 已实现 10 个 HTTP 接口,覆盖:
- 用户注册、登录、退出
- 个人信息查询与修改
- 粉丝身份管理(查看、添加、切换)
- 账户安全(修改密码)
📝 测试要点:
- 所有受保护接口都需要
Authorization: Bearer <token>Header - 修改密码和退出登录会使当前 Token 失效
- 切换粉丝身份会返回新的 Token
- 每个用户最多有 2 个粉丝身份
🎉 所有接口均已测试通过,可以进行前端对接!