7.6 KiB
7.6 KiB
Proto文件设计说明 - 3.1 认证Service层
一、设计依据
本proto设计基于以下技术文档:
- 微服务架构设计文档 - 确定服务职责和API设计
- 数据库设计文档 - 确定数据结构和字段定义
- 开发功能顺序文档 - 确定Service层接口需求
- JWT设计 - 确定Token相关字段和验证流程
二、核心设计要点
2.1 单Token方案
- ✅
LoginResponse和RegisterResponse只返回access_token - ✅
RefreshTokenRequest使用access_token刷新(不是refresh_token) - ✅ Token存储在
users.access_token字段中 - ✅ 单设备登录,新登录会覆盖旧Token
2.2 Token中包含star_id
- ✅ JWT Claims包含:
user_id,star_id,updated_at - ✅ 前端可以直接从Token解析获取
star_id - ✅ 无需额外拼接或传递
star_id
2.3 粉丝身份隔离
- ✅ 所有业务操作都基于
user_id + star_id - ✅
FanProfile使用联合唯一索引(user_id, star_id) - ✅ 切换身份时生成新Token(包含新的
star_id)
2.4 数据库字段映射
User表字段映射
message User {
int64 id = 1; // users.id
string mobile = 2; // users.mobile
string avatar_url = 3; // users.avatar_url
string global_wallet_address = 4; // users.global_wallet_address
bool is_active = 5; // users.is_active
int64 created_at = 6; // users.created_at
}
注意:不包含敏感字段(password_hash, access_token, token_expires_at)
FanProfile表字段映射
message FanProfile {
int64 id = 1; // fan_profiles.id
int64 user_id = 2; // fan_profiles.user_id
int64 star_id = 3; // fan_profiles.star_id(核心隔离键)
string nickname = 4; // fan_profiles.nickname
int32 level = 5; // fan_profiles.level
int32 times = 6; // fan_profiles.times(剩余铸造次数)
int32 social = 7; // fan_profiles.social(好友个数)
int64 experience = 8; // fan_profiles.experience
int64 coin_balance = 9; // fan_profiles.coin_balance
int64 crystal_balance = 10; // fan_profiles.crystal_balance
repeated string tags = 11; // fan_profiles.tags(JSONB数组)
int64 created_at = 12; // fan_profiles.created_at
}
三、认证相关消息设计
3.1 RegisterRequest / RegisterResponse
RegisterRequest:
mobile- 手机号(必填)password- 密码(必填)star_id- 选择第一个粉丝身份的明星ID(必填)nickname- 第一个粉丝身份的昵称(必填)
RegisterResponse:
base- 基础响应(状态码、消息、时间戳)access_token- JWT Token(已包含star_id)expires_in- Token过期时间(秒,7天=604800秒)user- 创建的用户信息fan_profile- 创建的粉丝档案
业务逻辑:
- 创建用户(
users表) - 创建第一个粉丝档案(
fan_profiles表,事务) - 生成JWT Token(包含
user_id,star_id,updated_at) - 更新用户Token(
users.access_token,users.token_expires_at)
3.2 LoginRequest / LoginResponse
LoginRequest:
mobile- 手机号(必填)password- 密码(必填)
LoginResponse:
base- 基础响应access_token- JWT Token(已包含star_id)expires_in- Token过期时间(秒)user- 用户信息fan_profile- 当前粉丝档案(根据Token中的star_id)fan_profiles- 用户的所有粉丝身份列表
业务逻辑:
- 根据手机号查询用户
- 验证密码(bcrypt比对)
- 验证用户是否激活
- 获取用户的粉丝档案列表
- 生成JWT Token(包含当前
star_id,从第一个粉丝档案获取) - 更新用户Token
3.3 RefreshTokenRequest / RefreshTokenResponse
RefreshTokenRequest:
access_token- 旧的access_token(单token方案)
RefreshTokenResponse:
base- 基础响应access_token- 新的Access Tokenexpires_in- Token过期时间(秒)
业务逻辑:
- 解析旧Token(即使过期也要解析)
- 查询用户
- 验证旧Token是否匹配数据库中的Token
- 验证
updated_at是否匹配(如果用户信息更新,Token失效) - 生成新Token
- 更新数据库中的Token
3.4 ValidateTokenRequest / ValidateTokenResponse
ValidateTokenRequest:
access_token- 要验证的Token
ValidateTokenResponse:
base- 基础响应user_id- Token关联的用户IDstar_id- Token关联的明星IDis_valid- Token是否有效expires_at- Token过期时间戳(毫秒)
业务逻辑:
- 解析Token
- 验证签名和过期时间
- 验证Token是否匹配数据库中的Token
- 验证
updated_at是否匹配 - 返回验证结果
3.5 LogoutRequest / LogoutResponse
LogoutRequest:
access_token- 要失效的Token(可选)
LogoutResponse:
base- 基础响应
业务逻辑:
- 从Token中提取
user_id - 清除用户Token(
users.access_token = NULL,users.token_expires_at = NULL)
四、消息设计原则
4.1 字段编号规则
- 1-15:常用字段(占用1字节)
- 16-2047:一般字段
- 不要重用已删除字段的编号
- 新增字段只能追加,不能删除
4.2 数据类型选择
- ID类型:使用
int64(支持大整数) - 时间戳:使用
int64(Unix时间戳,毫秒) - 布尔值:使用
bool - 数组:使用
repeated关键字 - 可选字段:proto3中所有字段默认都是可选的
4.3 命名规范
- 消息类型:PascalCase(如
RegisterRequest) - 字段名:snake_case(如
access_token) - RPC方法:PascalCase(如
Register)
4.4 响应结构
- 所有Response的第一个字段必须是
topfans.common.BaseResponse base = 1; BaseResponse包含状态码、错误消息、时间戳
五、REST API映射
使用 google.api.annotations 定义REST API路径:
rpc Login(LoginRequest) returns (LoginResponse) {
option (google.api.http) = {
post: "/api/v1/auth/login"
body: "*"
};
}
支持通过 grpc-gateway 自动生成REST API,无需手动实现HTTP路由。
六、与Service层接口的对应关系
Service接口 → Proto消息
| Service方法 | Request | Response |
|---|---|---|
Register(req) |
RegisterRequest |
RegisterResponse |
Login(req) |
LoginRequest |
LoginResponse |
Logout(req) |
LogoutRequest |
LogoutResponse |
RefreshToken(req) |
RefreshTokenRequest |
RefreshTokenResponse |
ValidateToken(req) |
ValidateTokenRequest |
ValidateTokenResponse |
注意:Service层接口应使用proto定义的类型,而不是原生类型。
七、后续扩展
当前proto定义覆盖了3.1认证Service层的需求。后续可以添加:
- 用户信息Service相关消息(已在proto中定义)
- 粉丝身份Service相关消息(已在proto中定义)
- 社交功能相关消息(后续添加)
八、验证检查清单
- 所有必需的消息类型已定义
- 字段类型与数据库设计一致
- 单Token方案已正确实现
- Token中包含
star_id的设计已体现 - 粉丝身份隔离设计已体现
- REST API路径已定义
- RPC服务定义完整
- 字段编号无冲突
- 命名规范一致
九、下一步
- 生成proto Go代码(运行
make proto或手动执行protoc命令) - 验证生成的代码可以正常导入
- 更新
pkg/errors/errors.go使用proto类型 - 开始开发Service层(使用proto类型)