package middlewares import ( "GoMembership/internal/config" "GoMembership/pkg/logger" "fmt" "net/http" "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 int64) (string, error) { token := jwt.NewWithClaims(jwtSigningMethod, jwt.MapClaims{ "user_id": userID, "exp": time.Now().Add(time.Minute * 10).Unix(), // Token expires in 10 Minutes }) logger.Error.Printf("token generated: %#v", token) return token.SignedString(jwtKey) } func verifyToken(tokenString string) (*jwt.Token, error) { if tokenString == "" { return nil, fmt.Errorf("Authorization token is required") } token, err := jwtParser.Parse(tokenString, func(_ *jwt.Token) (interface{}, error) { return jwtKey, nil }) if err != nil { return nil, err } if !token.Valid { return nil, fmt.Errorf("invalid token") } claims, ok := token.Claims.(jwt.MapClaims) if !ok { return nil, fmt.Errorf("invalid token claims") } exp, ok := claims["exp"].(float64) if !ok { return nil, fmt.Errorf("invalid expiration claim") } userID, ok := claims["user_id"].(float64) if !ok { logger.Error.Printf("Invalid user ID: %v", userID) return nil, fmt.Errorf("Invalid user ID") } if time.Now().Unix() > int64(exp) { return nil, fmt.Errorf("token expired") } return token, nil } func AuthMiddleware() gin.HandlerFunc { return func(c *gin.Context) { tokenString, err := c.Cookie("jwt") if err != nil { logger.Error.Printf("No Auth token: %v\n", err) c.JSON(http.StatusUnauthorized, gin.H{"error": "No Auth token"}) c.Abort() return } token, err := verifyToken(tokenString) if err != nil { logger.Error.Printf("Token is invalid: %v\n", err) c.JSON(http.StatusUnauthorized, gin.H{"error": "Auth token invalid"}) c.Abort() return } claims, _ := token.Claims.(jwt.MapClaims) userID, _ := claims["user_id"].(float64) // Generate a new token newToken, err := GenerateToken(int64(userID)) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to refresh token"}) c.Abort() return } c.SetCookie( "jwt", newToken, 10*60, // 10 minutes "/", "", true, true, ) c.Set("user_id", userID) c.Next() } }