package core import ( "errors" "fmt" "github.com/golang-jwt/jwt/v5" "time" ) type JwtTokens struct { AccessToken string `json:"access_token"` RefreshToken string `json:"refresh_token"` } const ( accessTokenExp = 5 * time.Minute refreshTokenExp = 30 * 24 * time.Hour ) var secret = []byte("your-secret-key") func NewJwtTokens(username string) (JwtTokens, error) { accessClaims := NewAccessClaim(username) refreshClaims := jwt.RegisteredClaims{ Subject: username, ExpiresAt: jwt.NewNumericDate(time.Now().Add(refreshTokenExp)), } accessJwt, err := EncodeAndSignClaims(accessClaims) if err != nil { return JwtTokens{}, err } refreshJwt, err := EncodeAndSignClaims(refreshClaims) if err != nil { return JwtTokens{}, err } return JwtTokens{ AccessToken: accessJwt, RefreshToken: refreshJwt, }, nil } func NewAccessClaim(username string) jwt.RegisteredClaims { return jwt.RegisteredClaims{ Subject: username, ExpiresAt: jwt.NewNumericDate(time.Now().Add(accessTokenExp)), } } func EncodeAndSignClaims(claims jwt.RegisteredClaims) (string, error) { token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) return token.SignedString(secret) } func ParseRefreshToken(refreshToken string) (*jwt.RegisteredClaims, error) { token, err := jwt.ParseWithClaims(refreshToken, &jwt.RegisteredClaims{}, func(token *jwt.Token) (interface{}, error) { return secret, nil }) if err != nil { return nil, fmt.Errorf("error parsing refresh token: %w", err) } claims, ok := token.Claims.(*jwt.RegisteredClaims) if !ok { return nil, errors.New("unable to parse claims") } return claims, nil } func ParseAccessToken(accessToken string) (*jwt.RegisteredClaims, error) { token, err := jwt.ParseWithClaims(accessToken, &jwt.RegisteredClaims{}, func(token *jwt.Token) (interface{}, error) { return secret, nil }) if err != nil { return nil, fmt.Errorf("error parsing refresh token: %w", err) } claims, ok := token.Claims.(*jwt.RegisteredClaims) if !ok { return nil, errors.New("unable to parse claims") } return claims, nil } func ClaimExpired(claims jwt.RegisteredClaims) error { if claims.ExpiresAt == nil { return errors.New("claim exp is nil") } if claims.ExpiresAt.Time.Before(time.Now()) { return nil } return errors.New("claim expired") }