{"record":{"id":"5bd82e27b5a67911","repo":"jeecgboot/JeecgBoot","slug":"token-5bd82e","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":103,"sourceCode":"        }\n        return lowAppId;\n    }\n\n    /**\n     * 验证Token\n     */\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        }","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/jeecgboot/JeecgBoot/blob/96fb33f5ec68516da0b0147da06b2eb0419e063a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/TokenUtils.java#L85-L121","documentation":"Thrown by TokenUtils.verifyToken when the X-Access-Token header (or token parameter) extracted from the request is null or blank. It is the first guard in the JWT verification chain and returns HTTP 401 via JeecgBoot401Exception. It fires before any signature or Redis lookup, so it is purely a presence check.","triggerScenarios":"Any authenticated request (controller behind the shiro/jwt filter) sent without the token header, with an empty Authorization value, or where a gateway/proxy stripped the header. Also occurs during dev when the frontend stores the token in localStorage but the interceptor does not attach it.","commonSituations":"User session expired and the token was cleared client-side but the page kept making AJAX calls; misconfigured nginx/cors stripping X-Access-Token; a script/Postman call that forgot the header; a logged-out tab still open.","solutions":["Attach the JWT to every authenticated request: header 'X-Access-Token: <token>' (JeecgBoot convention) or the configured token header.","After login, persist the returned token and have the axios/uni request interceptor read it from storage on each call.","Handle a 401 with the message 'token不能为空!' by redirecting the user to the login page rather than retrying.","If behind a gateway, verify it forwards X-Access-Token and Authorization headers unchanged."],"exampleFix":"// before (frontend interceptor missing header)\naxios.get('/sys/user/list')\n\n// after\naxios.interceptors.request.use(cfg => {\n  const token = Vue.ls.get('Access-Token');\n  if (token) cfg.headers['X-Access-Token'] = token;\n  return cfg;\n});","handlingStrategy":"validation","validationCode":"String token = request.getHeader(\"X-Access-Token\");\nif (StringUtils.isBlank(token)) {\n    response.setStatus(401);\n    return;\n}","typeGuard":"public static boolean hasToken(HttpServletRequest r){\n    String t = r.getHeader(\"X-Access-Token\");\n    return t != null && !t.trim().isEmpty() && !\"null\".equalsIgnoreCase(t);\n}","tryCatchPattern":"try { TokenUtils.verifyToken(request, commonApi, redisUtil); }\ncatch (JeecgBoot401Exception e) { response.sendError(401, e.getMessage()); }","preventionTips":["Centralize token attachment in an axios/uni interceptor.","Treat 'null' string tokens as absent.","Handle 401 globally by redirecting to login."],"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"}