This commit is contained in:
2026-04-20 11:34:35 +08:00
parent 957976db31
commit bdbd6ae7e9
22 changed files with 761 additions and 238 deletions

View File

@@ -3,9 +3,14 @@ package auth
import (
"context"
"fmt"
"net/http"
"math/rand"
"strings"
"time"
"bdrp-server/app/main/model"
"bdrp-server/common/xerr"
jwtx "bdrp-server/common/jwt"
"bdrp-server/pkg/lzkit/crypto"
"github.com/pkg/errors"
@@ -53,6 +58,11 @@ func (l *SendSmsLogic) SendSms(req *types.SendSmsReq) error {
if action == "" {
action = "login"
}
if action == "cancelAccount" {
if err := l.verifyCancelAccountSmsCaller(req); err != nil {
return err
}
}
secretKey := l.svcCtx.Config.Encrypt.SecretKey
encryptedMobile, err := crypto.EncryptMobile(req.Mobile, secretKey)
if err != nil {
@@ -121,3 +131,49 @@ func (l *SendSmsLogic) sendSmsRequest(mobile, code string) (*dysmsapi.SendSmsRes
runtime := &service.RuntimeOptions{}
return cli.SendSmsWithOptions(request, runtime)
}
// verifyCancelAccountSmsCaller 注销验证码:须携带与 Jwt 一致的登录态,且手机号与当前账号绑定一致
func (l *SendSmsLogic) verifyCancelAccountSmsCaller(req *types.SendSmsReq) error {
var authz string
if hr, ok := l.ctx.Value(captcha.HTTPRequestContextKey).(*http.Request); ok && hr != nil {
authz = strings.TrimSpace(hr.Header.Get("Authorization"))
}
if authz == "" {
return errors.Wrapf(xerr.NewErrCode(xerr.TOKEN_EXPIRE_ERROR), "请先登录后再获取注销验证码")
}
tokenStr := strings.TrimSpace(authz)
if len(tokenStr) > 7 && strings.EqualFold(tokenStr[:7], "Bearer ") {
tokenStr = strings.TrimSpace(tokenStr[7:])
}
claims, err := jwtx.ParseJwtToken(tokenStr, l.svcCtx.Config.JwtAuth.AccessSecret)
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.TOKEN_EXPIRE_ERROR), "登录已失效,请重新登录")
}
if claims.UserType != model.UserTypeNormal {
return errors.Wrapf(xerr.NewErrMsg("当前账号类型不支持注销验证码"), "cancelAccount sms")
}
user, err := l.svcCtx.UserModel.FindOne(l.ctx, claims.UserId)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return errors.Wrapf(xerr.NewErrCode(xerr.USER_NOT_FOUND), "用户不存在")
}
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询用户失败: %v", err)
}
if user.CancelledAt.Valid {
return errors.Wrapf(xerr.NewErrCode(xerr.USER_CANCELLED), "账号已注销")
}
if user.Disable == 1 {
return errors.Wrapf(xerr.NewErrCode(xerr.USER_DISABLED), "账号已被封禁")
}
if !user.Mobile.Valid || user.Mobile.String == "" {
return errors.Wrapf(xerr.NewErrMsg("请先绑定手机号后再注销账号"), "cancelAccount sms, 未绑定手机")
}
enc, err := crypto.EncryptMobile(req.Mobile, l.svcCtx.Config.Encrypt.SecretKey)
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "加密手机号失败: %v", err)
}
if enc != user.Mobile.String {
return errors.Wrapf(xerr.NewErrMsg("手机号与当前登录账号不一致"), "cancelAccount sms mobile mismatch")
}
return nil
}