paascloud/paascloud-master · error · UacBizException

UAC10011031

UAC10011031

Error message

验证码超时, 请重新发送验证码

What it means

UAC10011031 is thrown by the reset-password flow when HttpAesUtil.decrypt fails on the value stored under RedisKeyUtil.getResetPwdTokenKey(email). The token is AES-encrypted with a key read from Redis (forgetKey); if that key has expired or the stored value is not decryptable, the flow aborts with '验证码超时' (verification code timed out) and asks the user to request a new code.

Solutions

  1. Re-request the reset-password code so fresh forgetKey/token values are written to Redis, then retry promptly.
  2. Increase the TTL used when storing the reset token and the forgetKey.
  3. Verify all UAC instances use the same Redis host/database and key prefix (RedisKeyUtil.getResetPwdTokenKey).
  4. Catch UacBizException(UAC10011031) in the controller and return a clear 'code expired, resend' response rather than a 500.

Example fix

// before
String forgetKey = redisService.getKey(key); // may be null after TTL
HttpAesUtil.decrypt(forgetToken, forgetKey, false, forgetKey);
// after
if (StringUtils.isEmpty(forgetKey)) {
    throw new UacBizException(ErrorCodeEnum.UAC10011031);
}
HttpAesUtil.decrypt(forgetToken, forgetKey, false, forgetKey);
Defensive patterns

Strategy: try-catch

Validate before calling

String key = RedisKeyUtil.getResetPwdTokenKey(email);
String forgetKey = redisService.getKey(key);
if (StringUtils.isEmpty(forgetKey)) {
    return Result.fail("reset code expired, please request a new one");
}

Try / catch

try {
    resetPwdService.resetPwd(loginName, email, ...);
} catch (UacBizException e) {
    if ("UAC10011031".equals(e.getCode())) { return Result.fail(410, "code expired, resend"); }
    throw e;
}

Prevention

When it happens

Trigger: User submits the reset-password form after the reset token TTL in Redis expired; Redis restarted/flushed losing the forgetKey or the token; a different Redis instance/prefix between 'send code' and 'reset password'; token value corrupted in Redis.

Common situations: Long gap between requesting the code and submitting the form; dev environment sharing one Redis with flushall; mismatched spring.redis database indexes across UAC nodes behind a load balancer.

Related errors


AI-assisted analysis of paascloud/paascloud-master@781281a950 (2026-09-10). Data as JSON: /api/errors/3bdbebc0dd38583d. Report an issue: GitHub.

Appendix: source

Thrown at paascloud-provider/paascloud-provider-uac/src/main/java/com/paascloud/provider/service/impl/UacUserServiceImpl.java:874

		String loginPwd = forgetResetPasswordDto.getLoginPwd();
		String loginName = forgetResetPasswordDto.getLoginName();
		String email = forgetResetPasswordDto.getEmail();
		String emailCode = forgetResetPasswordDto.getEmailCode();

		Preconditions.checkArgument(!StringUtils.isEmpty(loginName), ErrorCodeEnum.UAC10011007.msg());
		Preconditions.checkArgument(!StringUtils.isEmpty(email), ErrorCodeEnum.UAC10011018.msg());
		Preconditions.checkArgument(!StringUtils.isEmpty(loginPwd), ErrorCodeEnum.UAC10011014.msg());
		Preconditions.checkArgument(!StringUtils.isEmpty(forgetToken), "非法操作");
		Preconditions.checkArgument(!StringUtils.isEmpty(emailCode), "验证码不能为空");

		// 验证token
		String key = RedisKeyUtil.getResetPwdTokenKey(email);
		String forgetKey = redisService.getKey(key);

		try {
			HttpAesUtil.decrypt(forgetToken, forgetKey, false, forgetKey);
		} catch (Exception e) {
			throw new UacBizException(ErrorCodeEnum.UAC10011031);
		}

		int count = this.countUserByLoginNameAndEmail(loginName, email);
		// 校验token
		if (count < 1) {
			throw new UacBizException(ErrorCodeEnum.UAC10011032, loginName, email);
		}
	}

	/**
	 * 删除用户菜单表
	 */
	private int deleteUserMenuList(UacUserMenu uacUserMenu) {
		int selCount = uacUserMenuMapper.selectCount(uacUserMenu);
		// 如果查询结果为空, 默认认为已删除成功
		if (selCount < 1) {
			return 1;
		}

View on GitHub (pinned to 781281a950)