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
- Re-login to obtain a fresh, complete token and ensure it is copied in full.
- Strip the 'Bearer ' prefix before assigning the token if sending via Authorization.
- Log the token's shape (length, segment count) in a debug branch to spot truncation — never log the token itself.
- 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
- Store the raw token without the 'Bearer ' prefix where the backend expects a bare JWT (x-token)
- Trim whitespace/newlines/quotes from tokens before sending
- Never truncate tokens when copying between tools; use clipboard-safe transfer
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.