package middlewares import ( "GoMembership/internal/config" "GoMembership/pkg/logger" "net/http" "strings" "time" "github.com/gin-gonic/gin" "github.com/golang-jwt/jwt/v5" ) var ( jwtKey = []byte(config.Auth.JWTSecret) jwtSigningMethod = jwt.SigningMethodHS256 jwtParser = jwt.NewParser(jwt.WithValidMethods([]string{jwtSigningMethod.Alg()})) ) func GenerateToken(userID string) (string, error) { token := jwt.NewWithClaims(jwtSigningMethod, jwt.MapClaims{ "user_id": userID, "exp": time.Now().Add(time.Minute * 15).Unix(), // Token expires in 15 Minutes }) return token.SignedString(jwtKey) } func verifyToken(tokenString string) (*jwt.Token, error) { token, err := jwtParser.Parse(tokenString, func(_ *jwt.Token) (interface{}, error) { return jwtKey, nil }) if err != nil { return nil, err } return token, nil } func AuthMiddleware() gin.HandlerFunc { return func(c *gin.Context) { authHeader := c.GetHeader("Authorization") if authHeader == "" { c.JSON(http.StatusUnauthorized, gin.H{"error": "Authorization header is required"}) c.Abort() return } bearerToken := strings.Split(authHeader, " ") if len(bearerToken) != 2 { c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token format"}) c.Abort() return } tokenString := bearerToken[1] token, err := verifyToken(tokenString) if err != nil { if err == jwt.ErrTokenSignatureInvalid { logger.Error.Printf("JWT NULL ATTACK: %#v", err) c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token signing method"}) } else { c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"}) } c.Abort() return } if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid { userID := claims["user_id"].(string) c.Set("user_id", userID) c.Next() } else { c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token claims"}) c.Abort() return } } }