[feature/backend] implement /auth/logout handling + overall enhancement
This commit is contained in:
parent
d8d8e4b0d7
commit
e5fc8691bf
12 changed files with 420 additions and 64 deletions
|
@ -2,6 +2,7 @@ package handler
|
|||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
@ -28,8 +29,8 @@ type AuthResponse struct {
|
|||
|
||||
func (h *Handler) Register(c *gin.Context) {
|
||||
// 检查是否启用注册功能
|
||||
if !h.config.Auth.Registration.Enabled {
|
||||
message := h.config.Auth.Registration.Message
|
||||
if !h.cfg.Auth.Registration.Enabled {
|
||||
message := h.cfg.Auth.Registration.Message
|
||||
if message == "" {
|
||||
message = "Registration is currently disabled"
|
||||
}
|
||||
|
@ -181,3 +182,72 @@ func (h *Handler) Login(c *gin.Context) {
|
|||
|
||||
c.JSON(http.StatusOK, AuthResponse{Token: tokenString})
|
||||
}
|
||||
|
||||
func (h *Handler) Logout(c *gin.Context) {
|
||||
// 获取当前用户ID
|
||||
userID, exists := c.Get("user_id")
|
||||
if !exists {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{
|
||||
"error": gin.H{
|
||||
"code": "UNAUTHORIZED",
|
||||
"message": "User not authenticated",
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 获取 token
|
||||
authHeader := c.GetHeader("Authorization")
|
||||
if authHeader == "" {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{
|
||||
"error": gin.H{
|
||||
"code": "UNAUTHORIZED",
|
||||
"message": "Authorization header is required",
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
parts := strings.Split(authHeader, " ")
|
||||
if len(parts) != 2 || parts[0] != "Bearer" {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{
|
||||
"error": gin.H{
|
||||
"code": "UNAUTHORIZED",
|
||||
"message": "Authorization header format must be Bearer {token}",
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 解析 token 以获取过期时间
|
||||
token, err := jwt.Parse(parts[1], func(token *jwt.Token) (interface{}, error) {
|
||||
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||
return nil, jwt.ErrSignatureInvalid
|
||||
}
|
||||
return []byte(h.cfg.JWT.Secret), nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{
|
||||
"error": gin.H{
|
||||
"code": "INVALID_TOKEN",
|
||||
"message": "Invalid token",
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
|
||||
// 将 token 添加到黑名单
|
||||
h.service.GetTokenBlacklist().AddToBlacklist(parts[1], claims)
|
||||
}
|
||||
|
||||
// 记录日志
|
||||
log.Info().
|
||||
Interface("user_id", userID).
|
||||
Msg("User logged out")
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "Successfully logged out",
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue