wuyouzhuguli/SpringAll · error · ValidateCodeException

验证码不存在!

Error message

验证码不存在!

What it means

ValidateCodeException thrown when the SmsCode looked up from session under SESSION_KEY_SMS_CODE + mobileInRequest is null. IMPORTANT BUG: SmsCodeFilter (project 61) reads mobileInRequest from the 'smsCode' parameter (getStringParameter(..., "smsCode")) instead of 'mobile', so the session key becomes SESSION_KEY_SMS_CODE + <the sms code value>, which never matches the key ValidateController stored under (SESSION_KEY_SMS_CODE + mobile). This error is therefore triggered even with a valid mobile and code.

Source

Thrown at 61.Spring-security-Permission/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

  1. Fix the copy-paste bug: read 'mobile' for mobileInRequest so the session key matches ValidateController's storage key.
  2. After the fix, ensure GET /code/sms?mobile=<num> was called in the same session before login.
  3. Share the JSESSIONID cookie across both requests; in clusters use Spring Session.

Example fix

// before
// String mobileInRequest = ServletRequestUtils.getStringParameter(req, "smsCode");

// after
String mobileInRequest = ServletRequestUtils.getStringParameter(req, "mobile");
Defensive patterns

Strategy: try-catch

Validate before calling

// This is a server-side bug; client cannot fully avoid it. After patching the filter,
// ensure GET /code/sms?mobile=<num> ran in the same session before login.
await fetch(`/code/sms?mobile=${mobile}`, { credentials:'same-origin' });

Try / catch

// Patch the filter first, then this becomes a normal 'generate-then-login' flow.
// Server fix:
// String mobileInRequest = ServletRequestUtils.getStringParameter(req, "mobile");
try { await smsLogin(); } catch (e) { if (/不存在/.test(e.message)) await resendSms(); }

Prevention

When it happens

Trigger: Any /login/mobile request, because the lookup key is built from the wrong parameter. Also genuinely triggered when the SMS code was never created (no prior GET /code/sms?mobile=...) or the session expired.

Common situations: Always-on bug in this sample project; developers copying this filter verbatim hit '验证码不存在' on every SMS login; session cookie not shared between /code/sms and /login/mobile.

Related errors


AI-assisted analysis of wuyouzhuguli/SpringAll@614d2578d9 (2026-08-14). Data as JSON: /api/errors/24b9eb55eba60820. Report an issue: GitHub.