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.
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)
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
- 验证码不存在或已过期
- 文件超出规定大小:{maxSize}MB
- {entity} 不存在: {parameter} is {value}
- 没有这个选项
AI-assisted analysis of elunez/eladmin@55fbf70595 (2026-08-14).
Data as JSON: /api/errors/0d0514352b61a868.
Report an issue: GitHub.