flipped-aurora/gin-vue-admin · error

这不是一个token

Error message

这不是一个token

What it means

TokenMalformed is returned by ParseToken when the token string cannot even be parsed as a JWT — e.g. it is not three dot-separated base64 segments. It maps the jwt.ErrTokenMalformed / parse-failure case of the underlying jwt library.

Source

Thrown at server/utils/jwt.go:21

import (
	"context"
	"errors"
	"time"

	"github.com/flipped-aurora/gin-vue-admin/server/global"
	"github.com/flipped-aurora/gin-vue-admin/server/model/system/request"
	jwt "github.com/golang-jwt/jwt/v5"
)

type JWT struct {
	SigningKey []byte
}

var (
	TokenValid            = errors.New("未知错误")
	TokenExpired          = errors.New("token已过期")
	TokenNotValidYet      = errors.New("token尚未激活")
	TokenMalformed        = errors.New("这不是一个token")
	TokenSignatureInvalid = errors.New("无效签名")
	TokenInvalid          = errors.New("无法处理此token")
)

func NewJWT() *JWT {
	return &JWT{
		[]byte(global.GVA_CONFIG.JWT.SigningKey),
	}
}

func (j *JWT) CreateClaims(baseClaims request.BaseClaims) request.CustomClaims {
	bf, _ := ParseDuration(global.GVA_CONFIG.JWT.BufferTime)
	ep, _ := ParseDuration(global.GVA_CONFIG.JWT.ExpiresTime)
	claims := request.CustomClaims{
		BaseClaims: baseClaims,
		BufferTime: int64(bf / time.Second), // 缓冲时间1天 缓冲时间内会获得新的token刷新令牌 此时一个用户会存在两个有效令牌 但是前端只留一个 另一个会丢失
		RegisteredClaims: jwt.RegisteredClaims{
			Audience:  jwt.ClaimStrings{"GVA"},                   // 受众

View on GitHub (pinned to 3136500ef3)

Solutions

  1. Re-login to obtain a fresh, complete token and ensure it is copied in full.
  2. Strip the 'Bearer ' prefix before assigning the token if sending via Authorization.
  3. Log the token's shape (length, segment count) in a debug branch to spot truncation — never log the token itself.
  4. Ensure the frontend stores the token unchanged (no extra quotes/newlines) when writing to localStorage/cookies.

Example fix

// before
const token = `Bearer ${localStorage.getItem('token')}` // sent into x-token
claims, err := utils.ParseToken(token) // 这不是一个token
// after
const token = localStorage.getItem('token').trim()
claims, err := utils.ParseToken(token) // ok
Defensive patterns

Strategy: validation

Validate before calling

token = strings.TrimSpace(strings.TrimPrefix(rawToken, "Bearer "))
if !looksLikeJWT(token) {
    return errors.New("malformed token: expected header.payload.signature")
}

Type guard

func looksLikeJWT(s string) bool {
    parts := strings.Split(s, ".")
    return len(parts) == 3 && parts[0] != "" && parts[1] != "" && parts[2] != ""
}

Try / catch

claims, err := utils.ParseToken(token)
if errors.Is(err, utils.TokenMalformed) {
    // 400-level: the client sent garbage; do not retry with same token
    return nil, ErrBadTokenFormat
}

Prevention

When it happens

Trigger: The x-token or Authorization header contains a truncated token, a JWT issued by a different format (e.g. a raw session id), a token with newlines/quotes copied from a terminal, or an empty/whitespace string that slips past other checks.

Common situations: Copy-paste truncation of the token; client sending a prefixed value like 'Bearer eyJ...' inside a header field expected to be the bare token (x-token); storage layer corrupting the token.

Related errors


AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31). Data as JSON: /api/errors/073188d4f26780cb. Report an issue: GitHub.