wuyouzhuguli/SpringAll · error · ValidateCodeException
验证码不存在!
Error message
验证码不存在!
What it means
ValidateCodeException thrown by SmsCodeFilter.validateCode() when codeInSession is null - no SmsCode in the session for this mobile. CRITICAL DEFECT: line 46 reads the request parameter 'smsCode' into mobileInRequest instead of 'mobile', so the session key is built as SESSION_KEY_SMS_CODE + smsCodeValue, which never matches the key used at generation (SESSION_KEY_SMS_CODE + mobile). Consequently this branch fires even when a valid code exists, unless the smsCode value coincidentally equals the mobile number.
Source
Thrown at 38.Spring-Security-SmsCode/src/main/java/cc/mrbird/validate/smscode/SmsCodeFilter.java:54
} catch (ValidateCodeException e) {
authenticationFailureHandler.onAuthenticationFailure(httpServletRequest, httpServletResponse, e);
return;
}
}
filterChain.doFilter(httpServletRequest, httpServletResponse);
}
private void validateCode(ServletWebRequest servletWebRequest) throws ServletRequestBindingException {
String smsCodeInRequest = ServletRequestUtils.getStringParameter(servletWebRequest.getRequest(), "smsCode");
String mobileInRequest = ServletRequestUtils.getStringParameter(servletWebRequest.getRequest(), "smsCode");
SmsCode codeInSession = (SmsCode) sessionStrategy.getAttribute(servletWebRequest, ValidateController.SESSION_KEY_SMS_CODE + mobileInRequest);
if (StringUtils.isBlank(smsCodeInRequest)) {
throw new ValidateCodeException("验证码不能为空!");
}
if (codeInSession == null) {
throw new ValidateCodeException("验证码不存在!");
}
if (codeInSession.isExpire()) {
sessionStrategy.removeAttribute(servletWebRequest, ValidateController.SESSION_KEY_IMAGE_CODE);
throw new ValidateCodeException("验证码已过期!");
}
if (!StringUtils.equalsIgnoreCase(codeInSession.getCode(), smsCodeInRequest)) {
throw new ValidateCodeException("验证码不正确!");
}
sessionStrategy.removeAttribute(servletWebRequest, ValidateController.SESSION_KEY_IMAGE_CODE);
}
}View on GitHub (pinned to 614d2578d9)
Solutions
- Fix line 46: read the 'mobile' parameter, not 'smsCode', so the session key matches the generation key.
- Ensure the SMS code was generated for the same mobile via /code/sms?mobile=... in the same session.
- Confirm the JSESSIONID cookie is shared between generation and login.
- Make sure the mobile value is byte-identical between generation and login (formatting, trimming).
Example fix
// before (line 46) String mobileInRequest = ServletRequestUtils.getStringParameter(servletWebRequest.getRequest(), "smsCode"); // after String mobileInRequest = ServletRequestUtils.getStringParameter(servletWebRequest.getRequest(), "mobile");
Defensive patterns
Strategy: retry
Validate before calling
// client: request an SMS code for the exact mobile, same session, before login
await fetch('/code/sms?mobile=' + encodeURIComponent(mobile), { credentials: 'same-origin' });
// then submit /login/mobile with the same mobile + the received smsCode Prevention
- Fix SmsCodeFilter line 46 to read the 'mobile' parameter, not 'smsCode', so the session key matches generation.
- Generate the SMS code for the same mobile and in the same JSESSIONID session used for login.
- Keep the mobile string byte-identical (trim, no formatting changes) between /code/sms and /login/mobile.
When it happens
Trigger: POST to /login/mobile; because mobileInRequest is sourced from the wrong parameter, the session lookup key is wrong and codeInSession is null even with a correctly generated SMS code. Also genuinely fires when no SMS code was generated for this mobile.
Common situations: The copy-paste bug on line 46 (reads 'smsCode' not 'mobile'); SMS code generated for a different mobile than submitted; JSESSIONID differs between /code/sms generation and login; code already consumed/removed.
Related errors
AI-assisted analysis of wuyouzhuguli/SpringAll@614d2578d9 (2026-08-14).
Data as JSON: /api/errors/c7f379fd1ba8de72.
Report an issue: GitHub.