package middleware import ( "net/http" "strings" "time" "github.com/gin-gonic/gin" "github.com/golang-jwt/jwt/v5" "airwallex-admin/config" ) func GenerateToken(username string) (string, error) { claims := jwt.MapClaims{ "sub": username, "exp": time.Now().Add(time.Duration(config.Cfg.JWTExpireMinutes) * time.Minute).Unix(), } token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) return token.SignedString([]byte(config.Cfg.SecretKey)) } func JWTAuth() gin.HandlerFunc { return func(c *gin.Context) { authHeader := c.GetHeader("Authorization") if authHeader == "" { c.JSON(http.StatusUnauthorized, gin.H{"detail": "Missing authorization header"}) c.Abort() return } parts := strings.SplitN(authHeader, " ", 2) if len(parts) != 2 || strings.ToLower(parts[0]) != "bearer" { c.JSON(http.StatusUnauthorized, gin.H{"detail": "Invalid authorization header format"}) c.Abort() return } tokenString := parts[1] token, err := jwt.Parse(tokenString, func(t *jwt.Token) (interface{}, error) { if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok { return nil, jwt.ErrSignatureInvalid } return []byte(config.Cfg.SecretKey), nil }) if err != nil || !token.Valid { c.JSON(http.StatusUnauthorized, gin.H{"detail": "Invalid or expired token"}) c.Abort() return } claims, ok := token.Claims.(jwt.MapClaims) if !ok { c.JSON(http.StatusUnauthorized, gin.H{"detail": "Invalid token claims"}) c.Abort() return } username, ok := claims["sub"].(string) if !ok { c.JSON(http.StatusUnauthorized, gin.H{"detail": "Invalid token subject"}) c.Abort() return } c.Set("username", username) c.Next() } }