code: func (mgm *tokenManager) ParseToken(ctx context.Context, tokenString string) (*TokenClaims, error) {
  	token, err := jwt.ParseWithClaims(tokenString, &TokenClaims{}, func(token *jwt.Token) (interface{}, error) {
  		kid, ok := token.Header["kid"]
  		if !ok {
  			log.Error(ctx, map[string]interface{}{}, "There is no 'kid' header in the token")
  			return nil, errors.New("there is no 'kid' header in the token")
  		}
  		key := mgm.PublicKey(fmt.Sprintf("%s", kid))
  		if key == nil {
  			log.Error(ctx, map[string]interface{}{
  				"kid": kid,
  			}, "There is no public key with such ID")
  			return nil, errors.Errorf("there is no public key with such ID: %s", kid)
  		}
  		return key, nil
  	})
  	if err != nil {
  		return nil, err
  	}
  	claims := token.Claims.(*TokenClaims)
  	if token.Valid {
  		return claims, nil
  	}
  	return nil, errors.WithStack(errors.New("token is not valid"))
  }
docs: // ParseToken parses token claims