feat: 实现 C 端完整认证系统(client-auth-system)

实现面向个人客户的 7 个认证接口(A1-A7),覆盖资产验证、
微信公众号/小程序登录、手机号绑定/换绑、退出登录完整流程。

主要变更:
- 新增 PersonalCustomerOpenID 模型,支持多 AppID 多 OpenID 管理
- 实现有状态 JWT(JWT + Redis 双重校验),支持服务端主动失效
- 扩展微信 SDK:小程序 Code2Session + 3 个 DB 动态工厂函数
- 实现 A1 资产验证 IP 限流(30/min)和 A4 三层验证码限流
- 新增 7 个错误码(1180-1186)和 6 个 Redis Key 函数
- 注册 /api/c/v1/auth/* 下 7 个端点并更新 OpenAPI 文档
- 数据库迁移 000083:新建 tb_personal_customer_openid 表
This commit is contained in:
2026-03-19 11:33:41 +08:00
parent ec86dbf463
commit df76e33105
35 changed files with 4348 additions and 1362 deletions

View File

@@ -53,6 +53,49 @@ func RedisShopSubordinatesKey(shopID uint) string {
return fmt.Sprintf("shop:subordinates:%d", shopID)
}
// ========================================
// 个人客户认证相关 Redis Key
// ========================================
// RedisPersonalCustomerTokenKey 生成个人客户登录令牌的 Redis 键
// 用途:有状态 JWT存储当前有效 token 字符串,支持服务端主动失效
// 过期时间:与 JWT 过期时间一致
func RedisPersonalCustomerTokenKey(customerID uint) string {
return fmt.Sprintf("personal:customer:token:%d", customerID)
}
// RedisClientAuthRateLimitIPKey 生成 C 端资产验证 IP 限流键
// 用途A1 接口 IP 级限频 30 次/分钟
// 过期时间1 分钟
func RedisClientAuthRateLimitIPKey(ip string) string {
return fmt.Sprintf("client:auth:ratelimit:ip:%s", ip)
}
// RedisClientSendCodePhoneLimitKey 生成验证码手机号冷却键
// 用途A4 接口同手机号 60 秒冷却
// 过期时间60 秒
func RedisClientSendCodePhoneLimitKey(phone string) string {
return fmt.Sprintf("client:auth:sendcode:phone:limit:%s", phone)
}
// RedisClientSendCodeIPHourKey 生成验证码 IP 小时限流键
// 用途A4 接口同 IP 每小时 20 次
// 过期时间1 小时
func RedisClientSendCodeIPHourKey(ip string) string {
return fmt.Sprintf("client:auth:sendcode:ip:hour:%s", ip)
}
// RedisClientSendCodePhoneDayKey 生成验证码手机号日限流键
// 用途A4 接口同手机号每日 10 次
// 过期时间:当日剩余时间
func RedisClientSendCodePhoneDayKey(phone string) string {
return fmt.Sprintf("client:auth:sendcode:phone:day:%s", phone)
}
// ========================================
// 验证码相关 Redis Key
// ========================================
// RedisVerificationCodeKey 生成验证码的 Redis 键
// 用途:存储手机验证码
// 过期时间5 分钟