{"record":{"id":"7140f2dd20c54d80","repo":"jeecgboot/JeecgBoot","slug":"token-7140f2","errorCode":null,"errorMessage":"token非法无效!","messagePattern":"token非法无效!","errorType":"exception","errorClass":"JeecgBoot401Exception","httpStatus":401,"severity":"error","filePath":"jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/TokenUtils.java","lineNumber":109,"sourceCode":"     */\n    public static boolean verifyToken(HttpServletRequest request, CommonAPI commonApi, RedisUtil redisUtil) {\n        log.debug(\" -- url --\" + request.getRequestURL());\n        String token = getTokenByRequest(request);\n        return TokenUtils.verifyToken(token, commonApi, redisUtil);\n    }\n\n    /**\n     * 验证Token\n     */\n    public static boolean verifyToken(String token, CommonAPI commonApi, RedisUtil redisUtil) {\n        if (StringUtils.isBlank(token)) {\n            throw new JeecgBoot401Exception(\"token不能为空!\");\n        }\n\n        // 解密获得username，用于和数据库进行对比\n        String username = JwtUtil.getUsername(token);\n        if (username == null) {\n            throw new JeecgBoot401Exception(\"token非法无效!\");\n        }\n\n        // 查询用户信息\n        LoginUser user = TokenUtils.getLoginUser(username, commonApi, redisUtil);\n        //LoginUser user = commonApi.getUserByName(username);\n        if (user == null) {\n            throw new JeecgBoot401Exception(\"用户不存在!\");\n        }\n        // 判断用户状态\n        if (user.getStatus() != 1) {\n            throw new JeecgBoot401Exception(\"账号已被锁定,请联系管理员!\");\n        }\n        // 校验token是否超时失效 & 或者账号密码是否错误\n        if (!jwtTokenRefresh(token, username, user.getPassword(), redisUtil)) {\n            // 用户登录Token过期提示信息\n            String userLoginTokenErrorMsg = oConvertUtils.getString(redisUtil.get(CommonConstant.PREFIX_USER_TOKEN_ERROR_MSG + token));\n            throw new JeecgBoot401Exception(oConvertUtils.isEmpty(userLoginTokenErrorMsg)? CommonConstant.TOKEN_IS_INVALID_MSG: userLoginTokenErrorMsg);\n        }","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/jeecgboot/JeecgBoot/blob/96fb33f5ec68516da0b0147da06b2eb0419e063a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/TokenUtils.java#L91-L127","documentation":"Thrown by TokenUtils.verifyToken when JwtUtil.getUsername(token) returns null — meaning the JWT either cannot be parsed, the signature is invalid, or the token has no 'username' claim. This is the signature/structure validation step; it precedes the Redis user lookup. Returns HTTP 401.","triggerScenarios":"Sending a malformed or truncated token string, a token signed with a different secret (e.g. dev secret used in prod), a tampered token whose signature no longer matches, or a non-JWT value (a plain session id or 'null' literal) placed in the header.","commonSituations":"The jwt secret (jeecg.signer or signature.secret) was changed/rotated between releases so old tokens fail; an environment variable for the secret was not set so a different default was used; a token from another JeecgBoot tenant; clock skew causing parsing edge cases.","solutions":["Force a fresh login so a new token is minted with the current secret and claims.","Verify the JWT signing secret is identical across all instances/services that issue or consume tokens (jeecg.jwt.secret / jeecg.signer).","Confirm the token is a real 3-part JWT (header.payload.signature) and not 'null' or 'Bearer null'.","Check that the username claim key matches what JwtUtil.getUsername reads (default 'username')."],"exampleFix":"// before\nString token = \"null\";          // stored literally\nTokenUtils.verifyToken(token, ...); // throws token非法无效\n\n// after\nif (\"null\".equals(token) || token == null) {\n    redirect to login;\n}","handlingStrategy":"try-catch","validationCode":"try {\n    Jwts.parser().setSigningKey(secret).parseClaimsJws(token);\n} catch (JwtException e) {\n    // token invalid -> force re-login\n}","typeGuard":"public static boolean isPlausibleJwt(String t){\n    return t != null && t.chars().filter(c -> c == '.').count() == 2;\n}","tryCatchPattern":"try { TokenUtils.verifyToken(token, commonApi, redisUtil); }\ncatch (JeecgBoot401Exception e) { if (e.getMessage().contains(\"非法\")) forceRelogin(); }","preventionTips":["Keep the JWT signing secret identical across all environments that consume tokens.","Reject 'null'/'undefined' literal tokens client-side.","Rotate secrets with a token-invalidation strategy."],"tags":["authentication","jwt","security","jeecg-boot","http-401"],"backgroundTag":null,"analyzedSha":"96fb33f5ec68516da0b0147da06b2eb0419e063a","analyzedAt":"2026-08-14T00:04:16.786Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}