{"record":{"id":"fdd82e7d1c460362","repo":"paascloud/paascloud-master","slug":"uac10011030","errorCode":"UAC10011030","errorMessage":"激活失败, 链接已过期","messagePattern":"激活失败, 链接已过期","errorType":"error_code","errorClass":"UacBizException","httpStatus":null,"severity":"error","filePath":"paascloud-provider/paascloud-provider-uac/src/main/java/com/paascloud/provider/service/impl/UacUserServiceImpl.java","lineNumber":759,"sourceCode":"\t\t\talreadyBindRoleIdSet.add(uacRoleUser.getRoleId());\n\t\t}\n\n\t\tuserBindRoleVo.setAllRoleSet(allUserSet);\n\t\tuserBindRoleVo.setAlreadyBindRoleIdSet(alreadyBindRoleIdSet);\n\n\t\treturn userBindRoleVo;\n\t}\n\n\t@Override\n\tpublic void activeUser(String activeUserToken) {\n\t\tPreconditions.checkArgument(!StringUtils.isEmpty(activeUserToken), \"激活用户失败\");\n\n\t\tString activeUserKey = RedisKeyUtil.getActiveUserKey(activeUserToken);\n\n\t\tString email = redisService.getKey(activeUserKey);\n\n\t\tif (StringUtils.isEmpty(email)) {\n\t\t\tthrow new UacBizException(ErrorCodeEnum.UAC10011030);\n\t\t}\n\t\t// 修改用户状态, 绑定访客角色\n\t\tUacUser uacUser = new UacUser();\n\t\tuacUser.setEmail(email);\n\n\t\tuacUser = uacUserMapper.selectOne(uacUser);\n\t\tif (uacUser == null) {\n\t\t\tlogger.error(\"找不到用户信息. email={}\", email);\n\t\t\tthrow new UacBizException(ErrorCodeEnum.UAC10011004, email);\n\t\t}\n\n\t\tUacUser update = new UacUser();\n\t\tupdate.setId(uacUser.getId());\n\t\tupdate.setStatus(UacUserStatusEnum.ENABLE.getKey());\n\t\tLoginAuthDto loginAuthDto = new LoginAuthDto();\n\t\tloginAuthDto.setUserId(uacUser.getId());\n\t\tloginAuthDto.setUserName(uacUser.getLoginName());\n\t\tloginAuthDto.setLoginName(uacUser.getLoginName());","sourceCodeStart":741,"sourceCodeEnd":777,"githubUrl":"https://github.com/paascloud/paascloud-master/blob/781281a9503332ed3cef44ea618349d14230a127/paascloud-provider/paascloud-provider-uac/src/main/java/com/paascloud/provider/service/impl/UacUserServiceImpl.java#L741-L777","documentation":"UAC10011030 is thrown by the user-activation flow (activeUser) when redisService.getKey(getActiveUserKey(activeUserToken)) returns null/empty. The registration flow stores the user's email in Redis under the activation token with a TTL; once the TTL expires (or the key was flushed), activation cannot map the token back to an email and fails with 'link expired'.","triggerScenarios":"User clicks the email activation link after the Redis TTL has elapsed; Redis restart/eviction removed the key; the token in the URL was truncated or never issued (wrong redis key prefix).","commonSituations":"Delayed email reading (activation links older than the TTL, commonly 24h); shared/ephemeral Redis in dev with default no-persistence config; environments pointing at different Redis instances so the key saved at registration is missing at activation.","solutions":["Ask the user to re-register or use the 'resend activation email' flow so a fresh token/key is written to Redis.","Increase the activation TTL when setting the key (e.g. redisService.setKey(activeUserKey, email, longerTimeout)) or persist the token in DB as a fallback.","Confirm the app issuing the email and the app handling activation point at the same Redis database/prefix (check spring.redis config and RedisKeyUtil.getActiveUserKey).","Enable Redis persistence (appendonly/AOF) or avoid flushing the shared instance so tokens survive restarts."],"exampleFix":"// before\nredisService.setKey(activeUserKey, email);\n// after\nredisService.setKey(activeUserKey, email, 7, TimeUnit.DAYS); // longer than email validity","handlingStrategy":"try-catch","validationCode":"String email = redisService.getKey(RedisKeyUtil.getActiveUserKey(token));\nif (StringUtils.isEmpty(email)) {\n    return Result.fail(\"activation link expired, please re-register or resend the email\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    uacUserService.activeUser(activeUserToken);\n} catch (UacBizException e) {\n    if (\"UAC10011030\".equals(e.getCode())) { return Result.fail(410, \"activation link expired\"); }\n    throw e;\n}","preventionTips":["Set an activation TTL comfortably longer than expected email delay (e.g. 7 days instead of hours).","Offer a 'resend activation email' endpoint that regenerates the Redis key.","Verify Redis persistence (AOF/RDB) so restarts don't wipe pending activation tokens.","Ensure dev/stage/prod Redis instances and key prefixes are not mixed up in configuration."],"tags":["redis","token-expired","activation"],"backgroundTag":"jwt-token-expired","analyzedSha":"781281a9503332ed3cef44ea618349d14230a127","analyzedAt":"2026-09-10T10:59:02.070Z","contentChangedAt":"2026-09-10T10:59:02.070Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}