{"record":{"id":"2f4cee41b6df4928","repo":"flipped-aurora/gin-vue-admin","slug":"error-2f4cee","errorCode":null,"errorMessage":"未知错误","messagePattern":"未知错误","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/utils/jwt.go","lineNumber":18,"sourceCode":"package utils\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"time\"\n\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipped-aurora/gin-vue-admin/server/model/system/request\"\n\tjwt \"github.com/golang-jwt/jwt/v5\"\n)\n\ntype JWT struct {\n\tSigningKey []byte\n}\n\nvar (\n\tTokenValid            = errors.New(\"未知错误\")\n\tTokenExpired          = errors.New(\"token已过期\")\n\tTokenNotValidYet      = errors.New(\"token尚未激活\")\n\tTokenMalformed        = errors.New(\"这不是一个token\")\n\tTokenSignatureInvalid = errors.New(\"无效签名\")\n\tTokenInvalid          = errors.New(\"无法处理此token\")\n)\n\nfunc NewJWT() *JWT {\n\treturn &JWT{\n\t\t[]byte(global.GVA_CONFIG.JWT.SigningKey),\n\t}\n}\n\nfunc (j *JWT) CreateClaims(baseClaims request.BaseClaims) request.CustomClaims {\n\tbf, _ := ParseDuration(global.GVA_CONFIG.JWT.BufferTime)\n\tep, _ := ParseDuration(global.GVA_CONFIG.JWT.ExpiresTime)\n\tclaims := request.CustomClaims{\n\t\tBaseClaims: baseClaims,","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/utils/jwt.go#L1-L36","documentation":"TokenValid is the sentinel error returned by ParseToken when token parsing fails with an error that matches none of the specific JWT sentinels (expired, not-valid-yet, malformed, bad signature, invalid). It is the catch-all '未知错误' bucket for unexpected token validation failures.","triggerScenarios":"ParseToken receives a token whose jwt.Parse error does not match the known sentinel switch: e.g. an entirely empty token string, an unexpected signing method, or a token signed with a different key causing an unmapped error path depending on library version.","commonSituations":"Proxy stripping/replacing the Authorization header value; client sending a token from a different deployment with a different SigningKey; misconfigured JWT.SigningKey in config.yaml; golang-jwt version upgrades changing error surfaces.","solutions":["Log the underlying raw error from ParseToken to see which jwt library error fell through to the default branch.","Verify JWT.SigningKey in config matches the one used to issue the token; regenerate a token with the correct key.","Confirm the client is sending a properly formed 'Bearer <token>' header and the token is not empty.","Check golang-jwt/jwt version compatibility between token issuance and validation code paths."],"exampleFix":"// before\ntoken := c.Request.Header.Get(\"x-token\") // empty or wrong key\nclaims, err := utils.ParseToken(token)   // 未知错误\n// after\nif token == \"\" {\n    c.AbortWithStatusJSON(401, ...)\n    return\n}\nclaims, err := utils.ParseToken(token) // valid token signed with GVA_CONFIG.JWT.SigningKey","handlingStrategy":"try-catch","validationCode":"if token == \"\" {\n    return errors.New(\"token is empty\")\n}\nif parts := strings.Split(token, \".\"); len(parts) != 3 {\n    return errors.New(\"token is not a JWT\")\n}","typeGuard":"func looksLikeJWT(s string) bool {\n    parts := strings.Split(s, \".\")\n    return len(parts) == 3 && parts[0] != \"\" && parts[2] != \"\"\n}","tryCatchPattern":"claims, err := utils.ParseToken(token)\nif err != nil {\n    switch {\n    case errors.Is(err, utils.TokenExpired):\n        // re-login/refresh\n    case errors.Is(err, utils.TokenNotValidYet), errors.Is(err, utils.TokenMalformed),\n        errors.Is(err, utils.TokenSignatureInvalid), errors.Is(err, utils.TokenInvalid),\n        errors.Is(err, utils.TokenValid):\n        // reject with 401\n    default:\n        log rawErr // unmapped fallback: investigate signing config\n    }\n}","preventionTips":["Keep JWT.SigningKey consistent across all environments that share tokens","Check errors.Is against every jwt sentinel exported in server/utils/jwt.go and log the raw error for the default branch","Validate the Authorization/x-token header shape before calling ParseToken"],"tags":["jwt","auth","go","token-validation"],"backgroundTag":"jwt-token-invalid","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}