hi-server/internal/handler/public/user/deleteAccountHandler.go
shanshanzhong ccdcfd3430
All checks were successful
Build docker and publish / build (20.15.1) (push) Successful in 6m55s
fix(account): 将删除账号接口从GET改为POST方法
修复删除账号接口的安全问题,GET方法不应用于敏感操作
同时增加邮箱验证码校验,提高账号安全性
```

```msg
feat(auth): 在设备登录时更新用户代理信息

添加设备登录时更新用户代理(UA)的逻辑
确保设备信息保持最新状态
```

```msg
refactor(handler): 重构删除账号处理器的验证逻辑

将邮箱验证码校验逻辑提取为独立函数
提高代码可维护性和复用性
2025-10-31 01:59:14 -07:00

70 lines
2.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package user
import (
"context"
"encoding/json"
"fmt"
"net/http"
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/public/user"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/pkg/constant"
"github.com/pkg/errors"
)
// DeleteAccountHandler 注销账号处理器
// 根据当前token删除所有关联设备然后根据各自设备ID重新新建账号
// 新增:需携带邮箱验证码,验证通过后执行注销
type deleteAccountReq struct {
EmailCode string `json:"email_code" binding:"required"` // 邮箱验证码
}
func DeleteAccountHandler(serverCtx *svc.ServiceContext) gin.HandlerFunc {
return func(c *gin.Context) {
var req deleteAccountReq
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request: " + err.Error()})
return
}
// 校验邮箱验证码
if err := verifyEmailCode(c.Request.Context(), serverCtx, req.EmailCode); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
l := user.NewDeleteAccountLogic(c.Request.Context(), serverCtx)
resp, err := l.DeleteAccount()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, resp)
}
}
type CacheKeyPayload struct {
Code string `json:"code"`
LastAt int64 `json:"lastAt"`
}
func verifyEmailCode(ctx context.Context, serverCtx *svc.ServiceContext, code string) error {
userEmail := ctx.Value("user_email").(string)
cacheKey := fmt.Sprintf("auth_code:%s:%s", constant.Security, userEmail)
val, err := serverCtx.Redis.Get(ctx, cacheKey).Result()
if err != nil {
return errors.Wrap(err, "failed to get cached code")
}
var payload CacheKeyPayload
if err := json.Unmarshal([]byte(val), &payload); err != nil {
return errors.Wrap(err, "invalid cached payload")
}
if payload.Code != code {
return errors.New("invalid email code")
}
// 验证通过,立即删除缓存,防止重复使用
_ = serverCtx.Redis.Del(ctx, cacheKey)
return nil
}