package jwt import ( "errors" "fmt" "strconv" "time" "github.com/golang-jwt/jwt/v5" "github.com/google/uuid" ) type Claims struct { Type string `json:"type"` jwt.RegisteredClaims } func GenerateAccessToken(userID int, secret string) (string, error) { now := time.Now() claims := Claims{ Type: "access", RegisteredClaims: jwt.RegisteredClaims{ Subject: strconv.Itoa(userID), ID: uuid.New().String(), IssuedAt: jwt.NewNumericDate(now), ExpiresAt: jwt.NewNumericDate(now.Add(15 * time.Minute)), }, } token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) return token.SignedString([]byte(secret)) } func GenerateRefreshToken(userID int, secret string) (string, error) { now := time.Now() claims := Claims{ Type: "refresh", RegisteredClaims: jwt.RegisteredClaims{ Subject: strconv.Itoa(userID), ID: uuid.New().String(), IssuedAt: jwt.NewNumericDate(now), ExpiresAt: jwt.NewNumericDate(now.Add(30 * 24 * time.Hour)), }, } token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) return token.SignedString([]byte(secret)) } func ValidateToken(tokenString, secret string) (*Claims, error) { token, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(token *jwt.Token) (interface{}, error) { 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, fmt.Errorf("failed to parse token: %w", err) } if claims, ok := token.Claims.(*Claims); ok && token.Valid { return claims, nil } return nil, errors.New("invalid token") } func GetUserIDFromToken(tokenString, secret string) (int, error) { claims, err := ValidateToken(tokenString, secret) if err != nil { return 0, err } userID, err := strconv.Atoi(claims.Subject) if err != nil { return 0, fmt.Errorf("invalid user ID in token: %w", err) } return userID, nil }