elunez/eladmin · error · BadRequestException

验证码不存在或已过期

Error message

验证码不存在或已过期

What it means

AuthController.login looks up the captcha in Redis by the client-supplied uuid (redisUtils.get(uuid)), deletes it immediately (one-time use), and if the stored code is blank throws '验证码不存在或已过期'. The captcha was either never stored, already consumed, or its TTL expired.

Source

Thrown at eladmin-system/src/main/java/me/zhengjie/modules/security/rest/AuthController.java:88

    private final OnlineUserService onlineUserService;
    private final TokenProvider tokenProvider;
    private final LoginProperties loginProperties;
    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);

View on GitHub (pinned to 55fbf70595)

Solutions

  1. Refresh the captcha image (fetches a new uuid+code) and log in promptly within the TTL.
  2. Prevent double submission in the frontend (disable the button while the request is in flight).
  3. Verify Redis connectivity and that the login code TTL (login.code.expiration, typically 2 minutes) suits your users.
  4. Ensure the Redis database/host config matches between environments if codes seem to vanish.

Example fix

// frontend pseudo-code
// before: reuse old uuid after failed attempt
login(oldUuid, code);
// after: always fetch a fresh captcha after any login failure
await getCode(); // sets new uuid + image
login(newUuid, inputCode);
Defensive patterns

Strategy: validation

Validate before calling

// frontend: ensure a live captcha accompanies every login attempt
if (!this.uuid || !this.code) { await this.getCode(); throw new Error('请先获取并填写验证码'); }
// and always refresh after any failed attempt:
catch (e) { await this.getCode(); throw e; }

Try / catch

try { await login(payload); } catch (e) { if (e.message.includes('验证码不存在或已过期')) { await refreshCaptcha(); focusCodeInput(); return; } throw e; }

Prevention

When it happens

Trigger: POST /auth/login with a uuid for which Redis has no entry: submitting after the captcha expired (default TTL is short), double-submitting the login form (first attempt consumed the code), Redis flushed/restarted without persistence, or the frontend sending a stale/absent uuid.

Common situations: User leaves the login page open past the captcha expiry then submits; double-click of the login button; Redis restart with no RDB/AOF so all captcha keys vanished; frontend bug reusing an old uuid; wrong Redis database index in config (code stored in another db than the one read).

Related errors


AI-assisted analysis of elunez/eladmin@55fbf70595 (2026-08-14). Data as JSON: /api/errors/3b595cbfcb3ab3f2. Report an issue: GitHub.