package auth import ( "errors" "fmt" "time" "github.com/golang-jwt/jwt/v5" ) // Claims represents the JWT claims type Claims struct { UserID uint `json:"user_id"` Email string `json:"email"` jwt.RegisteredClaims } // GenerateToken creates a new JWT token for a user func GenerateToken(userID uint, email, secret string, expirationTime time.Duration) (string, error) { // Create claims with user ID and expiration time claims := &Claims{ UserID: userID, Email: email, RegisteredClaims: jwt.RegisteredClaims{ ExpiresAt: jwt.NewNumericDate(time.Now().Add(expirationTime)), IssuedAt: jwt.NewNumericDate(time.Now()), NotBefore: jwt.NewNumericDate(time.Now()), Issuer: "gomft", Subject: fmt.Sprintf("%d", userID), }, } // Create token with claims token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) // Sign token with secret tokenString, err := token.SignedString([]byte(secret)) if err != nil { return "", err } return tokenString, nil } // ValidateToken validates a JWT token and returns the claims func ValidateToken(tokenString, secret string) (*Claims, error) { // Parse token token, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(token *jwt.Token) (interface{}, error) { // Validate signing method if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) } return []byte(secret), nil }) if err != nil { return nil, err } // Extract claims if claims, ok := token.Claims.(*Claims); ok && token.Valid { return claims, nil } return nil, errors.New("invalid token") }