wuyouzhuguli/SpringAll · warning · Exception

验证码不能为空!

Error message

验证码不能为空!

What it means

A plain java.lang.Exception with message '验证码不能为空!' (SMS code cannot be empty) is thrown by SmsCodeFilter.validateCode when the request carries no 'smsCode' parameter. The filter runs before the SMS authentication provider, so this is the input-validation gate of the SMS login flow. Throwing a raw Exception (rather than an AuthenticationException) is a code smell — it bypasses Spring Security's failure handler and produces a generic 500 unless the filter is wrapped.

Source

Thrown at 65.Spring-Security-OAuth2-Config/src/main/java/cc/mrbird/security/validate/smscode/SmsCodeFilter.java:49

                && StringUtils.equalsIgnoreCase(httpServletRequest.getMethod(), "post")) {
            try {
                validateCode(new ServletWebRequest(httpServletRequest));
            } catch (Exception e) {
                authenticationFailureHandler.onAuthenticationFailure(httpServletRequest, httpServletResponse, new AuthenticationServiceException(e.getMessage()));
                return;
            }
        }
        filterChain.doFilter(httpServletRequest, httpServletResponse);
    }

    private void validateCode(ServletWebRequest servletWebRequest) throws Exception {
        String smsCodeInRequest = ServletRequestUtils.getStringParameter(servletWebRequest.getRequest(), "smsCode");
        String mobileInRequest = ServletRequestUtils.getStringParameter(servletWebRequest.getRequest(), "mobile");

        String codeInRedis = redisCodeService.get(servletWebRequest, mobileInRequest);

        if (StringUtils.isBlank(smsCodeInRequest)) {
            throw new Exception("验证码不能为空!");
        }
        if (codeInRedis == null) {
            throw new Exception("验证码已过期!");
        }
        if (!StringUtils.equalsIgnoreCase(codeInRedis, smsCodeInRequest)) {
            throw new Exception("验证码不正确!");
        }
        redisCodeService.remove(servletWebRequest, mobileInRequest);

    }
}

View on GitHub (pinned to 614d2578d9)

Solutions

  1. Ensure the client sends a non-empty 'smsCode' form parameter matching the field name the filter reads via ServletRequestUtils.getStringParameter(request, "smsCode").
  2. Standardize the parameter name across client and filter — if the frontend posts 'code', align the filter's getStringParameter argument or update the client.
  3. Replace the generic 'throw new Exception' with an AuthenticationException subclass (e.g. a custom ValidateCodeException) so Spring's AuthenticationFailureHandler renders a proper 4xx instead of a 500.
  4. Add client-side required-field validation on the smsCode input to prevent submission of empty values.

Example fix

// before
if (StringUtils.isBlank(smsCodeInRequest)) {
    throw new Exception("验证码不能为空!");
}

// after — typed exception routed through the security failure handler
if (StringUtils.isBlank(smsCodeInRequest)) {
    throw new ValidateCodeException("验证码不能为空!");
}
Defensive patterns

Strategy: validation

Validate before calling

// Client/server guard before invoking the filter chain
String smsCode = request.getParameter("smsCode");
if (smsCode == null || smsCode.trim().isEmpty()) {
    response.sendError(HttpServletResponse.SC_BAD_REQUEST, "smsCode 参数缺失");
    return; // do not proceed to validateCode
}

Type guard

private boolean hasSmsCode(HttpServletRequest req) {
    String c = req.getParameter("smsCode");
    return c != null && !c.trim().isEmpty();
}

Try / catch

try {
    filterChain.doFilter(request, response);
} catch (Exception e) {
    if ("验证码不能为空!".equals(e.getMessage())) {
        response.sendError(400, "验证码不能为空");
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: A POST to the SMS login endpoint omits the 'smsCode' request parameter, or sends it empty/whitespace-only, so ServletRequestUtils.getStringParameter returns a blank value and StringUtils.isBlank is true. Any client (browser form missing the field, curl without -d smsCode=, or a frontend bug dropping the input) triggers it.

Common situations: Frontend form forgot to include the smsCode input name; the field was disabled or cleared before submit; the parameter name was renamed (e.g. 'code' vs 'smsCode') and the client/server disagree; or a bot/automated request hits the endpoint without the field.

Related errors


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