fish2018/pansou · error

invalid token

Error message

invalid token

What it means

After parsing, ValidateToken checks token.Valid; if the parser returned no error but the token is not valid (expired, malformed claims, failed validation), it returns this sentinel "invalid token" error.

Solutions

  1. Have the client obtain a fresh token via LoginHandler and retry
  2. Check for expiry specifically (errors.Is(err, jwt.ErrTokenExpired) / validate errors) and return 401 prompting re-login
  3. Implement token refresh so clients renew before expiry
  4. Synchronize server clocks if skew is the cause

Example fix

// before
claims, err := util.ValidateToken(tokenString, secret)
if err != nil { c.AbortWithStatusJSON(401, gin.H{"error": "unauthorized"}); return }
// after
claims, err := util.ValidateToken(tokenString, secret)
if err != nil {
    c.AbortWithStatusJSON(401, gin.H{"error": "invalid or expired token, please login again"})
    return
}
Defensive patterns

Strategy: try-catch

Validate before calling

// check expiry locally before calling API
claims, _, _ := parseUnverified(tokenString)
if claims != nil && time.Now().After(claims.ExpiresAt.Time) { refreshToken() }

Try / catch

claims, err := util.ValidateToken(tokenString, secret)
if err != nil {
    // treat as expired: redirect to login or refresh token
    c.AbortWithStatusJSON(401, gin.H{"error": "token expired"})
    return
}

Prevention

When it happens

Trigger: Validating an expired JWT (exp in the past), a token whose claims fail validation, or a tampered token that happens to parse but fails validity checks.

Common situations: Long-lived client sessions past expiry; clock skew between issuer and validator; user keeps using a token after secret rotation.

Understand the failure class

Related errors


AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07). Data as JSON: /api/errors/57e0d38da8a459bf. Report an issue: GitHub.

Appendix: source

Thrown at util/jwt.go:63

		return nil, errors.New("secret cannot be empty")
	}

	claims := &Claims{}

	token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
		// 验证签名算法
		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
			return nil, errors.New("unexpected signing method")
		}
		return []byte(secret), nil
	})

	if err != nil {
		return nil, err
	}

	if !token.Valid {
		return nil, errors.New("invalid token")
	}

	return claims, nil
}

View on GitHub (pinned to beaa561337)