{"record":{"id":"885be3cd65a94b8e","repo":"dromara/Sa-Token","slug":"jwt","errorCode":null,"errorMessage":"请配置 jwt 秘钥","messagePattern":"请配置 jwt 秘钥","errorType":"exception","errorClass":"SaJwtException","httpStatus":null,"severity":"critical","filePath":"sa-token-plugin/sa-token-jwt/src/main/java/cn/dev33/satoken/jwt/SaJwtTemplate.java","lineNumber":173,"sourceCode":"\t\treturn JWTSignerUtil.hs256(keyt.getBytes());\n\t}\n\n\t// ------ 解析 \n\n    /**\n     * jwt 解析\n\t *\n     * @param token Jwt-Token值 \n     * @param loginType 登录类型 \n     * @param keyt 秘钥\n     * @param isCheckTimeout 是否校验 timeout 字段\n     * @return 解析后的jwt 对象 \n     */\n    public JWT parseToken(String token, String loginType, String keyt, boolean isCheckTimeout) {\n\n    \t// 秘钥不可以为空\n    \tif(SaFoxUtil.isEmpty(keyt)) {\n    \t\tthrow new SaJwtException(\"请配置 jwt 秘钥\");\n    \t}\n\n    \t// 如果token为null \n    \tif(token == null) {\n    \t\tthrow new SaJwtException(\"jwt 字符串不可为空\");\n    \t}\n    \t\n    \t// 解析 \n    \tJWT jwt;\n    \ttry {\n    \t\tjwt = JWT.of(token);\n\t\t} catch (JWTException | JSONException e) {\n    \t\tthrow new SaJwtException(\"jwt 解析失败：\" + token, e).setCode(SaJwtErrorCode.CODE_30201);\n\t\t}\n    \tJSONObject payloads = jwt.getPayloads();\n    \t\n    \t// 校验 Token 签名\n\t\tboolean verify = jwt.setSigner(createSigner(keyt)).verify();","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/dromara/Sa-Token/blob/ac2c7f6e94a78573cf0bcb932dd8b04e68fad189/sa-token-plugin/sa-token-jwt/src/main/java/cn/dev33/satoken/jwt/SaJwtTemplate.java#L155-L191","documentation":"Thrown by SaJwtTemplate.parseToken when the keyt (jwt secret key) parameter is empty. Every JWT operation in sa-token (sign, parse, verify) requires the configured secret, so this is a hard configuration error, not a token error. No error code is set (defaults to the generic jwt exception code).","triggerScenarios":"Any JWT-mode token parse/verification when sa-token's jwt-secret-key configuration is missing or empty — e.g. SaManager.getSaTokenConfigOrSecond() returns a config without jwt-secret-key, or the keyt argument passed programmatically is an empty string.","commonSituations":"Adding the sa-token-jwt dependency (Simple/Mixin/Stateless mode) but forgetting the 'jwt-secret-key' line in application.yml; environment-specific config where the secret env var is unset in one profile; programmatic use of SaJwtTemplate without supplying a key.","solutions":["Set sa-token.jwt-secret-key in your configuration (yml/properties) to a non-empty secret","If configuring programmatically, ensure the config object's jwtSecretKey is set before any JWT call","Use an environment variable for the secret and verify it is present in every deployment profile"],"exampleFix":"# before (application.yml)\nsa-token:\n  jwt-secret-key:   # empty -> throws\n\n# after\nsa-token:\n  jwt-secret-key: ${SA_JWT_SECRET:please-change-me-32chars-min}","handlingStrategy":"validation","validationCode":"if (SaFoxUtil.isEmpty(saTokenConfig.getJwtSecretKey())) {\n    throw new IllegalStateException(\"sa-token.jwt-secret-key must be configured\"); // fail fast at startup\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Add a startup assertion for jwt-secret-key so misconfig fails at boot, not at first request","Use env-var injection and validate presence in every profile (dev/stage/prod)"],"tags":["sa-token","jwt","configuration","secret"],"backgroundTag":null,"analyzedSha":"ac2c7f6e94a78573cf0bcb932dd8b04e68fad189","analyzedAt":"2026-08-14T14:36:10.271Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}