实现面向个人客户的 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 表
104 lines
4.4 KiB
Go
104 lines
4.4 KiB
Go
package dto
|
||
|
||
// ========================================
|
||
// A1 资产验证
|
||
// ========================================
|
||
|
||
// VerifyAssetRequest A1 资产验证请求
|
||
type VerifyAssetRequest struct {
|
||
Identifier string `json:"identifier" validate:"required,min=1,max=50" required:"true" minLength:"1" maxLength:"50" description:"资产标识符(SN/IMEI/虚拟号/ICCID/MSISDN)"`
|
||
}
|
||
|
||
// VerifyAssetResponse A1 资产验证响应
|
||
type VerifyAssetResponse struct {
|
||
AssetToken string `json:"asset_token" description:"资产令牌(5分钟有效)"`
|
||
ExpiresIn int `json:"expires_in" description:"过期时间(秒)"`
|
||
}
|
||
|
||
// ========================================
|
||
// A2 公众号登录
|
||
// ========================================
|
||
|
||
// WechatLoginRequest A2 公众号登录请求
|
||
type WechatLoginRequest struct {
|
||
Code string `json:"code" validate:"required" required:"true" description:"微信OAuth授权码"`
|
||
AssetToken string `json:"asset_token" validate:"required" required:"true" description:"A1返回的资产令牌"`
|
||
}
|
||
|
||
// WechatLoginResponse A2/A3 登录统一响应
|
||
type WechatLoginResponse struct {
|
||
Token string `json:"token" description:"登录JWT令牌"`
|
||
NeedBindPhone bool `json:"need_bind_phone" description:"是否需要绑定手机号"`
|
||
IsNewUser bool `json:"is_new_user" description:"是否新创建用户"`
|
||
}
|
||
|
||
// ========================================
|
||
// A3 小程序登录
|
||
// ========================================
|
||
|
||
// MiniappLoginRequest A3 小程序登录请求
|
||
type MiniappLoginRequest struct {
|
||
Code string `json:"code" validate:"required" required:"true" description:"小程序登录凭证"`
|
||
AssetToken string `json:"asset_token" validate:"required" required:"true" description:"A1返回的资产令牌"`
|
||
Nickname string `json:"nickname" description:"用户昵称(前端授权后传入)"`
|
||
AvatarURL string `json:"avatar_url" description:"用户头像URL(前端授权后传入)"`
|
||
}
|
||
|
||
// ========================================
|
||
// A4 发送验证码
|
||
// ========================================
|
||
|
||
// ClientSendCodeRequest A4 发送验证码请求
|
||
type ClientSendCodeRequest struct {
|
||
Phone string `json:"phone" validate:"required,len=11" required:"true" minLength:"11" maxLength:"11" description:"手机号"`
|
||
Scene string `json:"scene" validate:"required,oneof=bind_phone change_phone_old change_phone_new" required:"true" description:"业务场景 (bind_phone:绑定手机号, change_phone_old:换绑旧手机, change_phone_new:换绑新手机)"`
|
||
}
|
||
|
||
// ClientSendCodeResponse A4 发送验证码响应
|
||
type ClientSendCodeResponse struct {
|
||
CooldownSeconds int `json:"cooldown_seconds" description:"冷却秒数"`
|
||
}
|
||
|
||
// ========================================
|
||
// A5 绑定手机号
|
||
// ========================================
|
||
|
||
// BindPhoneRequest A5 绑定手机号请求
|
||
type BindPhoneRequest struct {
|
||
Phone string `json:"phone" validate:"required,len=11" required:"true" minLength:"11" maxLength:"11" description:"手机号"`
|
||
Code string `json:"code" validate:"required,len=6" required:"true" minLength:"6" maxLength:"6" description:"验证码"`
|
||
}
|
||
|
||
// BindPhoneResponse A5 绑定手机号响应
|
||
type BindPhoneResponse struct {
|
||
Phone string `json:"phone" description:"已绑定手机号"`
|
||
BoundAt string `json:"bound_at" description:"绑定时间"`
|
||
}
|
||
|
||
// ========================================
|
||
// A6 换绑手机号
|
||
// ========================================
|
||
|
||
// ChangePhoneRequest A6 换绑手机号请求
|
||
type ChangePhoneRequest struct {
|
||
OldPhone string `json:"old_phone" validate:"required,len=11" required:"true" minLength:"11" maxLength:"11" description:"旧手机号"`
|
||
OldCode string `json:"old_code" validate:"required,len=6" required:"true" minLength:"6" maxLength:"6" description:"旧手机号验证码"`
|
||
NewPhone string `json:"new_phone" validate:"required,len=11" required:"true" minLength:"11" maxLength:"11" description:"新手机号"`
|
||
NewCode string `json:"new_code" validate:"required,len=6" required:"true" minLength:"6" maxLength:"6" description:"新手机号验证码"`
|
||
}
|
||
|
||
// ChangePhoneResponse A6 换绑手机号响应
|
||
type ChangePhoneResponse struct {
|
||
Phone string `json:"phone" description:"换绑后手机号"`
|
||
ChangedAt string `json:"changed_at" description:"换绑时间"`
|
||
}
|
||
|
||
// ========================================
|
||
// A7 退出登录
|
||
// ========================================
|
||
|
||
// LogoutResponse A7 退出登录响应
|
||
type LogoutResponse struct {
|
||
Success bool `json:"success" description:"是否成功"`
|
||
}
|