package token import ( "encoding/base64" "encoding/json" "fmt" "strings" "time" ) // DecodePayload decodes the payload (claims) of a JWT without verifying the signature. func DecodePayload(tokenStr string) (map[string]interface{}, error) { parts := strings.Split(tokenStr, ".") if len(parts) != 3 { return nil, fmt.Errorf("invalid JWT: expected 3 parts, got %d", len(parts)) } payload, err := base64.RawURLEncoding.DecodeString(parts[1]) if err != nil { return nil, fmt.Errorf("decoding JWT payload: %w", err) } var claims map[string]interface{} if err := json.Unmarshal(payload, &claims); err != nil { return nil, fmt.Errorf("unmarshaling JWT payload: %w", err) } return claims, nil } // ExpiryInfo extracts the expiry time and remaining duration from JWT claims. func ExpiryInfo(claims map[string]interface{}) (exp time.Time, remaining time.Duration) { expVal, ok := claims["exp"] if !ok { return time.Time{}, 0 } expFloat, ok := expVal.(float64) if !ok { return time.Time{}, 0 } exp = time.Unix(int64(expFloat), 0) remaining = time.Until(exp) return exp, remaining }