{"record":{"id":"de217191069f3f78","repo":"jeecgboot/JeecgBoot","slug":"token-de2171","errorCode":null,"errorMessage":"Token非法无效!","messagePattern":"Token非法无效!","errorType":"exception","errorClass":"AuthenticationException","httpStatus":401,"severity":"error","filePath":"jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroRealm.java","lineNumber":128,"sourceCode":"            loginUser = this.checkUserTokenIsEffect(token);\n        } catch (AuthenticationException e) {\n            log.error(\"—————校验 check token 失败——————————\"+ e.getMessage(), e);\n            // 重新抛出异常，让JwtFilter统一处理，避免返回两次错误响应\n            throw e;\n        }\n        return new SimpleAuthenticationInfo(loginUser, token, getName());\n    }\n\n    /**\n     * 校验token的有效性\n     *\n     * @param token\n     */\n    public LoginUser checkUserTokenIsEffect(String token) throws AuthenticationException {\n        // 解密获得username，用于和数据库进行对比\n        String username = JwtUtil.getUsername(token);\n        if (username == null) {\n            throw new AuthenticationException(\"Token非法无效!\");\n        }\n\n        // 查询用户信息\n        log.debug(\"———校验token是否有效————checkUserTokenIsEffect——————— \"+ token);\n        LoginUser loginUser = TokenUtils.getLoginUser(username, commonApi, redisUtil);\n        //LoginUser loginUser = commonApi.getUserByName(username);\n        if (loginUser == null) {\n            throw new AuthenticationException(\"用户不存在!\");\n        }\n        // 判断用户状态\n        if (loginUser.getStatus() != 1) {\n            throw new AuthenticationException(\"账号已被锁定,请联系管理员!\");\n        }\n        // 校验token是否超时失效 & 或者账号密码是否错误\n        if (!jwtTokenRefresh(token, username, loginUser.getPassword())) {\n            // 用户登录Token过期提示信息\n            String userLoginTokenErrorMsg = oConvertUtils.getString(redisUtil.get(CommonConstant.PREFIX_USER_TOKEN_ERROR_MSG + token));\n            throw new AuthenticationException(oConvertUtils.isEmpty(userLoginTokenErrorMsg)? CommonConstant.TOKEN_IS_INVALID_MSG: userLoginTokenErrorMsg);","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/jeecgboot/JeecgBoot/blob/96fb33f5ec68516da0b0147da06b2eb0419e063a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroRealm.java#L110-L146","documentation":"Thrown by ShiroRealm.checkUserTokenIsEffect() when JwtUtil.getUsername(token) returns null — the JWT token cannot be decoded to extract a username. This means the token is structurally invalid, corrupted, signed with a different secret, or not a valid JWT at all. The method uses JwtUtil (jjwt library) to parse the token and extract the 'username' claim.","triggerScenarios":"Token is a random string (not a JWT); token is a JWT but signed with a different secret (e.g., after server restart with a new secret, or environment mismatch); token is truncated or has extra characters; token payload does not contain a 'username' claim.","commonSituations":"Server's JWT signing secret was changed (jeecg.jwt.secret config) invalidating all existing tokens; token was manually modified by the user; environment migration (dev→prod) with different secrets; token from a different JeecgBoot instance; clock skew causing JWT parsing issues.","solutions":["Have the user log out and log in again to obtain a fresh token signed with the current server secret.","Verify that the JWT signing secret (jeecg.jwt.secret in application.yml) is consistent across all environments and instances.","Check that the token is not truncated — inspect the header value for completeness (three base64 segments separated by dots).","Ensure the JwtUtil implementation matches between token generation and validation (same library version, same claim names)."],"exampleFix":"// No code fix — user must re-authenticate.\n// Verify JWT secret consistency:\n// application-dev.yml:\n//   jeecg:\n//     jwt:\n//       secret: <same-secret-in-all-envs>\n// Front-end: on 401 with 'Token非法无效', force logout and redirect to /login","handlingStrategy":"try-catch","validationCode":"// Verify token structure before sending (front-end)\nfunction isValidJwt(token) {\n    const parts = token.split('.');\n    return parts.length === 3;\n}\nif (!isValidJwt(token)) {\n    // re-authenticate\n}","typeGuard":null,"tryCatchPattern":"// Handled by JwtFilter — returns 401 with token error message\n// Front-end: on 401 'Token非法无效', force logout:\naxios.interceptors.response.use(null, error => {\n    if (error.response?.status === 401 && error.response.data?.message?.includes('非法无效')) {\n        store.dispatch('Logout');\n        router.push('/user/login');\n    }\n});","preventionTips":["Keep the JWT signing secret consistent across all environments and instances.","Force re-authentication after rotating the JWT secret.","Verify tokens are not truncated or modified in transit."],"tags":["shiro","jwt","authentication","token","invalid-token"],"backgroundTag":null,"analyzedSha":"96fb33f5ec68516da0b0147da06b2eb0419e063a","analyzedAt":"2026-08-14T00:04:16.786Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}