elunez/eladmin · warning · BadRequestException
验证码错误
Error message
验证码错误
What it means
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.
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.
Defensive patterns
Strategy: validation
Validate before calling
// frontend: trim and require non-empty code, and re-read arith captchas as results
const code = this.code.trim();
if (!code) { toast('请输入验证码'); return; }
submitLogin({ ...form, code }); Try / catch
try { await login(payload); } catch (e) { if (e.message.includes('验证码错误')) { await refreshCaptcha(); toast('验证码不正确,已刷新,请重试'); return; } throw e; } Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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).
Related errors
- 验证码不存在或已过期
- 验证码配置信息错误!正确配置查看 LoginCodeEnum
- A new dept cannot already have an ID
- A new dict cannot already have an ID
- A new dictDetail cannot already have an ID
AI-assisted analysis of elunez/eladmin@55fbf70595 (2026-08-14).
Data as JSON: /api/errors/0d0514352b61a868.
Report an issue: GitHub.
Appendix: source
Thrown at eladmin-system/src/main/java/me/zhengjie/modules/security/rest/AuthController.java:91
private final CaptchaConfig captchaConfig;
private final PasswordEncoder passwordEncoder;
private final UserDetailsServiceImpl userDetailsService;
@Log("用户登录")
@ApiOperation("登录授权")
@AnonymousPostMapping(value = "/login")
public ResponseEntity<Object> login(@Validated @RequestBody AuthUserDto authUser, HttpServletRequest request) throws Exception {
// 密码解密
String password = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey, authUser.getPassword());
// 查询验证码
String code = redisUtils.get(authUser.getUuid(), String.class);
// 清除验证码
redisUtils.del(authUser.getUuid());
if (StringUtils.isBlank(code)) {
throw new BadRequestException("验证码不存在或已过期");
}
if (StringUtils.isBlank(authUser.getCode()) || !authUser.getCode().equalsIgnoreCase(code)) {
throw new BadRequestException("验证码错误");
}
// 获取用户信息
JwtUserDto jwtUser = userDetailsService.loadUserByUsername(authUser.getUsername());
// 验证用户密码
if (!passwordEncoder.matches(password, jwtUser.getPassword())) {
throw new BadRequestException("登录密码错误");
}
Authentication authentication = new UsernamePasswordAuthenticationToken(jwtUser, null, jwtUser.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
// 生成令牌
String token = tokenProvider.createToken(jwtUser);
// 返回 token 与 用户信息
Map<String, Object> authInfo = new HashMap<String, Object>(2) {{
put("token", properties.getTokenStartWith() + token);
put("user", jwtUser);
}};
if (loginProperties.isSingleLogin()) {
// 踢掉之前已经登录的tokenView on GitHub (pinned to 55fbf70595)