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

  1. Fix line 46: read the 'mobile' parameter, not 'smsCode', so the session key matches the generation key.
  2. Ensure the SMS code was generated for the same mobile via /code/sms?mobile=... in the same session.
  3. Confirm the JSESSIONID cookie is shared between generation and login.
  4. 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

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.