{"record":{"id":"c7f379fd1ba8de72","repo":"wuyouzhuguli/SpringAll","slug":"error-c7f379","errorCode":null,"errorMessage":"验证码不存在！","messagePattern":"验证码不存在！","errorType":"exception","errorClass":"ValidateCodeException","httpStatus":null,"severity":"error","filePath":"38.Spring-Security-SmsCode/src/main/java/cc/mrbird/validate/smscode/SmsCodeFilter.java","lineNumber":54,"sourceCode":"            } catch (ValidateCodeException e) {\n                authenticationFailureHandler.onAuthenticationFailure(httpServletRequest, httpServletResponse, e);\n                return;\n            }\n        }\n        filterChain.doFilter(httpServletRequest, httpServletResponse);\n    }\n\n    private void validateCode(ServletWebRequest servletWebRequest) throws ServletRequestBindingException {\n        String smsCodeInRequest = ServletRequestUtils.getStringParameter(servletWebRequest.getRequest(), \"smsCode\");\n        String mobileInRequest = ServletRequestUtils.getStringParameter(servletWebRequest.getRequest(), \"smsCode\");\n\n        SmsCode codeInSession = (SmsCode) sessionStrategy.getAttribute(servletWebRequest, ValidateController.SESSION_KEY_SMS_CODE + mobileInRequest);\n\n        if (StringUtils.isBlank(smsCodeInRequest)) {\n            throw new ValidateCodeException(\"验证码不能为空！\");\n        }\n        if (codeInSession == null) {\n            throw new ValidateCodeException(\"验证码不存在！\");\n        }\n        if (codeInSession.isExpire()) {\n            sessionStrategy.removeAttribute(servletWebRequest, ValidateController.SESSION_KEY_IMAGE_CODE);\n            throw new ValidateCodeException(\"验证码已过期！\");\n        }\n        if (!StringUtils.equalsIgnoreCase(codeInSession.getCode(), smsCodeInRequest)) {\n            throw new ValidateCodeException(\"验证码不正确！\");\n        }\n        sessionStrategy.removeAttribute(servletWebRequest, ValidateController.SESSION_KEY_IMAGE_CODE);\n\n    }\n}","sourceCodeStart":36,"sourceCodeEnd":66,"githubUrl":"https://github.com/wuyouzhuguli/SpringAll/blob/614d2578d9495acf53cc02f2dee9c6131cc5e51a/38.Spring-Security-SmsCode/src/main/java/cc/mrbird/validate/smscode/SmsCodeFilter.java#L36-L66","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"// before (line 46)\nString mobileInRequest = ServletRequestUtils.getStringParameter(servletWebRequest.getRequest(), \"smsCode\");\n\n// after\nString mobileInRequest = ServletRequestUtils.getStringParameter(servletWebRequest.getRequest(), \"mobile\");","handlingStrategy":"retry","validationCode":"// client: request an SMS code for the exact mobile, same session, before login\nawait fetch('/code/sms?mobile=' + encodeURIComponent(mobile), { credentials: 'same-origin' });\n// then submit /login/mobile with the same mobile + the received smsCode","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["spring-security","sms-code","captcha","bug","session"],"backgroundTag":null,"analyzedSha":"614d2578d9495acf53cc02f2dee9c6131cc5e51a","analyzedAt":"2026-08-14T04:40:03.488Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}