package jwt import ( "errors" "strings" "time" "github.com/golang-jwt/jwt/v5" "github.com/spf13/viper" ) type JWT struct { key []byte } type MyCustomClaims struct { UserId string jwt.RegisteredClaims } func NewJwt(conf *viper.Viper) *JWT { return &JWT{key: []byte(conf.GetString("security.jwt.key"))} } func (j *JWT) GenToken(userId string, expiresAt time.Time) (string, error) { token := jwt.NewWithClaims(jwt.SigningMethodHS256, MyCustomClaims{ UserId: userId, RegisteredClaims: jwt.RegisteredClaims{ ExpiresAt: jwt.NewNumericDate(expiresAt), IssuedAt: jwt.NewNumericDate(time.Now()), NotBefore: jwt.NewNumericDate(time.Now()), Issuer: "", Subject: "", ID: "", Audience: []string{}, }, }) // Sign and get the complete encoded token as a string using the key tokenString, err := token.SignedString(j.key) if err != nil { return "", err } return tokenString, nil } func (j *JWT) ParseToken(tokenString string) (*MyCustomClaims, error) { tokenString = strings.TrimPrefix(tokenString, "Bearer ") if strings.TrimSpace(tokenString) == "" { return nil, errors.New("token is empty") } token, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, func(token *jwt.Token) (interface{}, error) { return j.key, nil }) if err != nil { return nil, err } if claims, ok := token.Claims.(*MyCustomClaims); ok && token.Valid { return claims, nil } else { return nil, err } }