{"record":{"id":"5d6d356b088e71d3","repo":"wuyouzhuguli/SpringAll","slug":"error-5d6d35","errorCode":null,"errorMessage":"验证码不正确！","messagePattern":"验证码不正确！","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"warning","filePath":"65.Spring-Security-OAuth2-Config/src/main/java/cc/mrbird/security/validate/smscode/SmsCodeFilter.java","lineNumber":55,"sourceCode":"            }\n        }\n        filterChain.doFilter(httpServletRequest, httpServletResponse);\n    }\n\n    private void validateCode(ServletWebRequest servletWebRequest) throws Exception {\n        String smsCodeInRequest = ServletRequestUtils.getStringParameter(servletWebRequest.getRequest(), \"smsCode\");\n        String mobileInRequest = ServletRequestUtils.getStringParameter(servletWebRequest.getRequest(), \"mobile\");\n\n        String codeInRedis = redisCodeService.get(servletWebRequest, mobileInRequest);\n\n        if (StringUtils.isBlank(smsCodeInRequest)) {\n            throw new Exception(\"验证码不能为空！\");\n        }\n        if (codeInRedis == null) {\n            throw new Exception(\"验证码已过期！\");\n        }\n        if (!StringUtils.equalsIgnoreCase(codeInRedis, smsCodeInRequest)) {\n            throw new Exception(\"验证码不正确！\");\n        }\n        redisCodeService.remove(servletWebRequest, mobileInRequest);\n\n    }\n}","sourceCodeStart":37,"sourceCodeEnd":60,"githubUrl":"https://github.com/wuyouzhuguli/SpringAll/blob/614d2578d9495acf53cc02f2dee9c6131cc5e51a/65.Spring-Security-OAuth2-Config/src/main/java/cc/mrbird/security/validate/smscode/SmsCodeFilter.java#L37-L60","documentation":"A plain java.lang.Exception '验证码不正确！' (verification code incorrect) is thrown by SmsCodeFilter.validateCode when the code stored in Redis does not equal the code submitted in the request (case-insensitive comparison via StringUtils.equalsIgnoreCase). It is the mismatch branch of the SMS-code validation gate, reached only after the empty-code and expired checks pass.","triggerScenarios":"The request's 'smsCode' parameter differs from the value stored under the mobile's Redis key: user mistyped the code, the code was generated for a different mobile, or the stored value was overwritten by a newer send (the key now holds a code the user did not request). Transient whitespace or a trailing newline from copy-paste can also cause a mismatch despite a case-insensitive compare.","commonSituations":"Typo on the numeric keypad; stale code displayed because the user requested a resend and entered the first (now-overwritten) code; frontend cached an old code; or the SMS gateway delivered codes out of order so the user typed an earlier one.","solutions":["Have the user re-enter the most recent code received, ensuring no leading/trailing whitespace or newline is included.","Confirm the code submitted corresponds to the same mobile used as the Redis key (mismatched mobile vs code is a common cause).","If resends overwrite the same key, document that only the last-sent code is valid; consider rate-limiting resends to avoid user confusion.","Trim the request parameter before comparison to absorb whitespace from copy-paste, and keep the comparison case-insensitive (already done).","Replace the raw Exception with a ValidateCodeException so the failure is reported as a 4xx through the security failure handler."],"exampleFix":"// before\nif (!StringUtils.equalsIgnoreCase(codeInRedis, smsCodeInRequest)) {\n    throw new Exception(\"验证码不正确！\");\n}\n\n// after — trim input + typed exception\nString submitted = StringUtils.trim(smsCodeInRequest);\nif (!StringUtils.equalsIgnoreCase(codeInRedis, submitted)) {\n    throw new ValidateCodeException(\"验证码不正确！\");\n}","handlingStrategy":"validation","validationCode":"// Compare before invoking the throwing filter chain\nString stored = redisCodeService.get(new ServletWebRequest(request), mobile);\nString submitted = request.getParameter(\"smsCode\");\nif (stored == null || !stored.equalsIgnoreCase(submitted == null ? \"\" : submitted.trim())) {\n    return \"验证码不正确，请重新输入\";\n}","typeGuard":"private boolean codeMatches(ServletWebRequest req, String mobile) {\n    String stored = redisCodeService.get(req, mobile);\n    String submitted = ServletRequestUtils.getStringParameter(req.getRequest(), \"smsCode\");\n    return stored != null && submitted != null\n        && stored.equalsIgnoreCase(submitted.trim());\n}","tryCatchPattern":"try {\n    filterChain.doFilter(request, response);\n} catch (Exception e) {\n    if (\"验证码不正确！\".equals(e.getMessage())) {\n        response.setStatus(400);\n        response.getWriter().write(\"验证码不正确\");\n    } else {\n        throw e;\n    }\n}","preventionTips":["Have the user enter only the most recent code received, since resends overwrite the same Redis key.","Trim whitespace/newlines from the submitted code before comparison to absorb copy-paste artifacts.","Ensure the mobile used as the Redis key is the same one the code was issued for.","Throw a typed ValidateCodeException instead of raw Exception so the failure routes through Spring Security's failure handler."],"tags":["spring-security","sms-code","validation","mismatch","filter"],"backgroundTag":null,"analyzedSha":"614d2578d9495acf53cc02f2dee9c6131cc5e51a","analyzedAt":"2026-08-14T04:40:03.488Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}