{"record":{"id":"0d0514352b61a868","repo":"elunez/eladmin","slug":"error-0d0514","errorCode":null,"errorMessage":"验证码错误","messagePattern":"验证码错误","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"warning","filePath":"eladmin-system/src/main/java/me/zhengjie/modules/security/rest/AuthController.java","lineNumber":91,"sourceCode":"    private final CaptchaConfig captchaConfig;\n    private final PasswordEncoder passwordEncoder;\n    private final UserDetailsServiceImpl userDetailsService;\n\n    @Log(\"用户登录\")\n    @ApiOperation(\"登录授权\")\n    @AnonymousPostMapping(value = \"/login\")\n    public ResponseEntity<Object> login(@Validated @RequestBody AuthUserDto authUser, HttpServletRequest request) throws Exception {\n        // 密码解密\n        String password = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey, authUser.getPassword());\n        // 查询验证码\n        String code = redisUtils.get(authUser.getUuid(), String.class);\n        // 清除验证码\n        redisUtils.del(authUser.getUuid());\n        if (StringUtils.isBlank(code)) {\n            throw new BadRequestException(\"验证码不存在或已过期\");\n        }\n        if (StringUtils.isBlank(authUser.getCode()) || !authUser.getCode().equalsIgnoreCase(code)) {\n            throw new BadRequestException(\"验证码错误\");\n        }\n        // 获取用户信息\n        JwtUserDto jwtUser = userDetailsService.loadUserByUsername(authUser.getUsername());\n        // 验证用户密码\n        if (!passwordEncoder.matches(password, jwtUser.getPassword())) {\n            throw new BadRequestException(\"登录密码错误\");\n        }\n        Authentication authentication = new UsernamePasswordAuthenticationToken(jwtUser, null, jwtUser.getAuthorities());\n        SecurityContextHolder.getContext().setAuthentication(authentication);\n        // 生成令牌\n        String token = tokenProvider.createToken(jwtUser);\n        // 返回 token 与 用户信息\n        Map<String, Object> authInfo = new HashMap<String, Object>(2) {{\n            put(\"token\", properties.getTokenStartWith() + token);\n            put(\"user\", jwtUser);\n        }};\n        if (loginProperties.isSingleLogin()) {\n            // 踢掉之前已经登录的token","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/elunez/eladmin/blob/55fbf705956949697dbd68bf9003776609d3d029/eladmin-system/src/main/java/me/zhengjie/modules/security/rest/AuthController.java#L73-L109","documentation":"After confirming a captcha exists in Redis, AuthController.login compares it case-insensitively (equalsIgnoreCase) with the submitted code; blank submission or any mismatch (beyond case) throws '验证码错误'. The stored code is already deleted at this point, so the user must refresh the captcha and retry.","triggerScenarios":"POST /auth/login where authUser.code differs from the Redis-stored value: misreading arith captcha answers (e.g. '3+2=?' answered as the expression), misreading chinese/gif characters, or the frontend sending the wrong field/whitespace.","commonSituations":"Arithmetic captcha misunderstanding — users sometimes type the whole equation instead of the result; case differences are fine but character errors are not; frontend trimming/encoding issues; user resubmitting a previously typed code after the uuid was refreshed (mismatch against the NEW code).","solutions":["Enter exactly the captcha answer: for arith type the RESULT of the math expression, matching characters for chinese types (case-insensitive for letters).","If unsure or after any failed login, click the captcha image to refresh and re-enter.","Frontend: send code.trim() and re-fetch captcha whenever a new uuid is issued."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// frontend: trim and require non-empty code, and re-read arith captchas as results\nconst code = this.code.trim();\nif (!code) { toast('请输入验证码'); return; }\nsubmitLogin({ ...form, code });","typeGuard":null,"tryCatchPattern":"try { await login(payload); } catch (e) { if (e.message.includes('验证码错误')) { await refreshCaptcha(); toast('验证码不正确，已刷新，请重试'); return; } throw e; }","preventionTips":["For arith captchas enter the RESULT (e.g. '7'), never the expression ('3+4').","Always refresh an unclear captcha instead of guessing — case is ignored, characters are not.","After any failure refresh the captcha, since the consumed code cannot be reused."],"tags":["captcha","login","validation","user-input"],"backgroundTag":null,"analyzedSha":"55fbf705956949697dbd68bf9003776609d3d029","analyzedAt":"2026-08-14T11:56:12.758Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}