diff --git a/src/main/java/com/label/common/shiro/TokenFilter.java b/src/main/java/com/label/common/shiro/TokenFilter.java index 9d7c6c7..2f893f0 100644 --- a/src/main/java/com/label/common/shiro/TokenFilter.java +++ b/src/main/java/com/label/common/shiro/TokenFilter.java @@ -13,7 +13,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.label.common.context.CompanyContext; import com.label.common.result.Result; import com.label.service.RedisService; -import com.label.util.RedisKeyManager; +import com.label.util.RedisUtil; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; @@ -98,7 +98,7 @@ public class TokenFilter extends OncePerRequestFilter { } String token = parts[1]; // String token = authHeader.substring(7).trim(); - Map tokenData = redisService.hGetAll(RedisKeyManager.tokenKey(token)); + Map tokenData = redisService.hGetAll(RedisUtil.tokenKey(token)); if (tokenData == null || tokenData.isEmpty()) { writeUnauthorized(response, "令牌已过期或不存在"); @@ -117,8 +117,8 @@ public class TokenFilter extends OncePerRequestFilter { TokenPrincipal principal = new TokenPrincipal(userId, role, companyId, username, token); SecurityUtils.getSubject().login(new BearerToken(token, principal)); request.setAttribute("__token_principal__", principal); - redisService.expire(RedisKeyManager.tokenKey(token), tokenTtlSeconds); - redisService.expire(RedisKeyManager.userSessionsKey(userId), tokenTtlSeconds); + redisService.expire(RedisUtil.tokenKey(token), tokenTtlSeconds); + redisService.expire(RedisUtil.userSessionsKey(userId), tokenTtlSeconds); filterChain.doFilter(request, response); } catch (Exception e) { diff --git a/src/main/java/com/label/common/shiro/UserRealm.java b/src/main/java/com/label/common/shiro/UserRealm.java index bc99ed6..fb9af18 100644 --- a/src/main/java/com/label/common/shiro/UserRealm.java +++ b/src/main/java/com/label/common/shiro/UserRealm.java @@ -1,7 +1,7 @@ package com.label.common.shiro; import com.label.service.RedisService; -import com.label.util.RedisKeyManager; +import com.label.util.RedisUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -56,7 +56,7 @@ public class UserRealm extends AuthorizingRealm { } private String getRoleFromCacheOrPrincipal(TokenPrincipal principal) { - String permKey = RedisKeyManager.userPermKey(principal.getUserId()); + String permKey = RedisUtil.userPermKey(principal.getUserId()); String cachedRole = redisService.get(permKey); if (cachedRole != null && !cachedRole.isEmpty()) { return cachedRole; diff --git a/src/main/java/com/label/service/AuthService.java b/src/main/java/com/label/service/AuthService.java index ffe7b57..98921a7 100644 --- a/src/main/java/com/label/service/AuthService.java +++ b/src/main/java/com/label/service/AuthService.java @@ -9,7 +9,7 @@ import com.label.entity.SysCompany; import com.label.entity.SysUser; import com.label.mapper.SysCompanyMapper; import com.label.mapper.SysUserMapper; -import com.label.util.RedisKeyManager; +import com.label.util.RedisUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -83,10 +83,10 @@ public class AuthService { tokenData.put("role", user.getRole()); tokenData.put("companyId", user.getCompanyId().toString()); tokenData.put("username", user.getUsername()); - redisService.hSetAll(RedisKeyManager.tokenKey(token), tokenData, tokenTtlSeconds); + redisService.hSetAll(RedisUtil.tokenKey(token), tokenData, tokenTtlSeconds); // 将 token 加入该用户的活跃会话集合(用于角色变更时批量更新/失效) - String sessionsKey = RedisKeyManager.userSessionsKey(user.getId()); + String sessionsKey = RedisUtil.userSessionsKey(user.getId()); redisService.sAdd(sessionsKey, token); // 防止 Set 无限增长:TTL = token 有效期(最后一次登录时滑动续期) redisService.expire(sessionsKey, tokenTtlSeconds); @@ -103,11 +103,11 @@ public class AuthService { public void logout(String token) { if (token != null && !token.isBlank()) { // 从用户会话集合中移除(若 token 仍有效则先读取 userId) - String userId = redisService.hGet(RedisKeyManager.tokenKey(token), "userId"); - redisService.delete(RedisKeyManager.tokenKey(token)); + String userId = redisService.hGet(RedisUtil.tokenKey(token), "userId"); + redisService.delete(RedisUtil.tokenKey(token)); if (userId != null) { try { - redisService.sRemove(RedisKeyManager.userSessionsKey(Long.parseLong(userId)), token); + redisService.sRemove(RedisUtil.userSessionsKey(Long.parseLong(userId)), token); } catch (NumberFormatException ignored) {} } log.info("用户退出,Token 已删除: {}", token); diff --git a/src/main/java/com/label/service/TaskClaimService.java b/src/main/java/com/label/service/TaskClaimService.java index 7ecd9dc..2db50c3 100644 --- a/src/main/java/com/label/service/TaskClaimService.java +++ b/src/main/java/com/label/service/TaskClaimService.java @@ -9,7 +9,7 @@ import com.label.entity.AnnotationTask; import com.label.entity.AnnotationTaskHistory; import com.label.mapper.AnnotationTaskMapper; import com.label.mapper.TaskHistoryMapper; -import com.label.util.RedisKeyManager; +import com.label.util.RedisUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -48,7 +48,7 @@ public class TaskClaimService { */ @Transactional public void claim(Long taskId, TokenPrincipal principal) { - String lockKey = RedisKeyManager.taskClaimKey(taskId); + String lockKey = RedisUtil.taskClaimKey(taskId); // 1. Redis SET NX 预锁(快速失败) boolean lockAcquired = redisService.setIfAbsent( @@ -104,7 +104,7 @@ public class TaskClaimService { .set(AnnotationTask::getClaimedAt, null)); // 清除 Redis 分布式锁 - redisService.delete(RedisKeyManager.taskClaimKey(taskId)); + redisService.delete(RedisUtil.taskClaimKey(taskId)); insertHistory(taskId, principal.getCompanyId(), "IN_PROGRESS", "UNCLAIMED", @@ -145,7 +145,7 @@ public class TaskClaimService { // 重新设置 Redis 锁(防止并发再次争抢) redisService.setIfAbsent( - RedisKeyManager.taskClaimKey(taskId), + RedisUtil.taskClaimKey(taskId), principal.getUserId().toString(), CLAIM_LOCK_TTL); insertHistory(taskId, principal.getCompanyId(), diff --git a/src/main/java/com/label/service/UserService.java b/src/main/java/com/label/service/UserService.java index 5dbe50e..a3f28ab 100644 --- a/src/main/java/com/label/service/UserService.java +++ b/src/main/java/com/label/service/UserService.java @@ -15,7 +15,7 @@ import com.label.common.result.PageResult; import com.label.common.shiro.TokenPrincipal; import com.label.entity.SysUser; import com.label.mapper.SysUserMapper; -import com.label.util.RedisKeyManager; +import com.label.util.RedisUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -126,11 +126,11 @@ public class UserService { .set(SysUser::getRole, newRole)); // 2. 更新所有活跃 Token 中的 role 字段(立即生效,无需重新登录) - Set tokens = redisService.sMembers(RedisKeyManager.userSessionsKey(userId)); - tokens.forEach(token -> redisService.hPut(RedisKeyManager.tokenKey(token), "role", newRole)); + Set tokens = redisService.sMembers(RedisUtil.userSessionsKey(userId)); + tokens.forEach(token -> redisService.hPut(RedisUtil.tokenKey(token), "role", newRole)); // 3. 删除权限缓存(如 Shiro 缓存存在) - redisService.delete(RedisKeyManager.userPermKey(userId)); + redisService.delete(RedisUtil.userPermKey(userId)); log.info("用户角色已变更: userId={}, newRole={}, 更新 {} 个活跃 Token", userId, newRole, tokens.size()); } @@ -159,14 +159,14 @@ public class UserService { // 禁用时:删除所有活跃 Token(立即失效) if ("DISABLED".equals(newStatus)) { - Set tokens = redisService.sMembers(RedisKeyManager.userSessionsKey(userId)); - tokens.forEach(token -> redisService.delete(RedisKeyManager.tokenKey(token))); - redisService.delete(RedisKeyManager.userSessionsKey(userId)); + Set tokens = redisService.sMembers(RedisUtil.userSessionsKey(userId)); + tokens.forEach(token -> redisService.delete(RedisUtil.tokenKey(token))); + redisService.delete(RedisUtil.userSessionsKey(userId)); log.info("账号已禁用,已删除 {} 个活跃 Token: userId={}", tokens.size(), userId); } // 删除权限缓存 - redisService.delete(RedisKeyManager.userPermKey(userId)); + redisService.delete(RedisUtil.userPermKey(userId)); } // ------------------------------------------------------------------ 查询 -- diff --git a/src/main/java/com/label/util/RedisKeyManager.java b/src/main/java/com/label/util/RedisUtil.java similarity index 91% rename from src/main/java/com/label/util/RedisKeyManager.java rename to src/main/java/com/label/util/RedisUtil.java index 8adb2ed..a158be1 100644 --- a/src/main/java/com/label/util/RedisKeyManager.java +++ b/src/main/java/com/label/util/RedisUtil.java @@ -4,9 +4,10 @@ package com.label.util; * Centralized Redis key naming conventions. * All keys follow the pattern: prefix:{id} */ -public final class RedisKeyManager { +public final class RedisUtil { - private RedisKeyManager() {} + private RedisUtil() { + } /** Session token key: token:{uuid} */ public static String tokenKey(String uuid) { diff --git a/src/test/java/com/label/integration/ExportIntegrationTest.java b/src/test/java/com/label/integration/ExportIntegrationTest.java index 4c59a2c..6be8c30 100644 --- a/src/test/java/com/label/integration/ExportIntegrationTest.java +++ b/src/test/java/com/label/integration/ExportIntegrationTest.java @@ -2,7 +2,7 @@ package com.label.integration; import com.label.AbstractIntegrationTest; import com.label.service.RedisService; -import com.label.util.RedisKeyManager; +import com.label.util.RedisUtil; import org.junit.jupiter.api.*; import org.springframework.beans.factory.annotation.Autowired; @@ -48,11 +48,11 @@ public class ExportIntegrationTest extends AbstractIntegrationTest { "SELECT id FROM sys_user WHERE username = 'admin'", Long.class); // 伪造 Redis Token - redisService.hSetAll(RedisKeyManager.tokenKey(ADMIN_TOKEN), + redisService.hSetAll(RedisUtil.tokenKey(ADMIN_TOKEN), Map.of("userId", userId.toString(), "role", "ADMIN", "companyId", companyId.toString(), "username", "admin"), 3600L); - redisService.hSetAll(RedisKeyManager.tokenKey(ANNOTATOR_TOKEN), + redisService.hSetAll(RedisUtil.tokenKey(ANNOTATOR_TOKEN), Map.of("userId", "3", "role", "ANNOTATOR", "companyId", companyId.toString(), "username", "annotator01"), 3600L); @@ -93,8 +93,8 @@ public class ExportIntegrationTest extends AbstractIntegrationTest { @AfterEach void cleanupTokens() { - redisService.delete(RedisKeyManager.tokenKey(ADMIN_TOKEN)); - redisService.delete(RedisKeyManager.tokenKey(ANNOTATOR_TOKEN)); + redisService.delete(RedisUtil.tokenKey(ADMIN_TOKEN)); + redisService.delete(RedisUtil.tokenKey(ANNOTATOR_TOKEN)); } // ------------------------------------------------------------------ 权限测试 -- diff --git a/src/test/java/com/label/integration/MultiTenantIsolationTest.java b/src/test/java/com/label/integration/MultiTenantIsolationTest.java index 2ac5a28..91c7f71 100644 --- a/src/test/java/com/label/integration/MultiTenantIsolationTest.java +++ b/src/test/java/com/label/integration/MultiTenantIsolationTest.java @@ -2,7 +2,7 @@ package com.label.integration; import com.label.AbstractIntegrationTest; import com.label.service.RedisService; -import com.label.util.RedisKeyManager; +import com.label.util.RedisUtil; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -68,11 +68,11 @@ public class MultiTenantIsolationTest extends AbstractIntegrationTest { Long.class, companyBId); // 伪造 Redis Token - redisService.hSetAll(RedisKeyManager.tokenKey(TOKEN_A), + redisService.hSetAll(RedisUtil.tokenKey(TOKEN_A), Map.of("userId", adminAId.toString(), "role", "ADMIN", "companyId", companyAId.toString(), "username", "admin"), 3600L); - redisService.hSetAll(RedisKeyManager.tokenKey(TOKEN_B), + redisService.hSetAll(RedisUtil.tokenKey(TOKEN_B), Map.of("userId", adminBId.toString(), "role", "ADMIN", "companyId", companyBId.toString(), "username", "admin_b"), 3600L); @@ -96,8 +96,8 @@ public class MultiTenantIsolationTest extends AbstractIntegrationTest { @AfterEach void cleanupTokensAndCompanyB() { - redisService.delete(RedisKeyManager.tokenKey(TOKEN_A)); - redisService.delete(RedisKeyManager.tokenKey(TOKEN_B)); + redisService.delete(RedisUtil.tokenKey(TOKEN_A)); + redisService.delete(RedisUtil.tokenKey(TOKEN_B)); // 清理公司 B 的数据(sys_company 不在 cleanData TRUNCATE 范围内) jdbcTemplate.execute("DELETE FROM sys_user WHERE username = 'admin_b'"); jdbcTemplate.execute("DELETE FROM sys_company WHERE company_code = 'TESTB'"); diff --git a/src/test/java/com/label/integration/ShiroFilterIntegrationTest.java b/src/test/java/com/label/integration/ShiroFilterIntegrationTest.java index 1884e81..ef85234 100644 --- a/src/test/java/com/label/integration/ShiroFilterIntegrationTest.java +++ b/src/test/java/com/label/integration/ShiroFilterIntegrationTest.java @@ -3,7 +3,7 @@ package com.label.integration; import com.label.AbstractIntegrationTest; import com.label.common.result.Result; import com.label.service.RedisService; -import com.label.util.RedisKeyManager; +import com.label.util.RedisUtil; import org.apache.shiro.SecurityUtils; import org.junit.jupiter.api.AfterEach; @@ -85,7 +85,7 @@ public class ShiroFilterIntegrationTest extends AbstractIntegrationTest { reviewerData.put("role", "REVIEWER"); reviewerData.put("companyId", "1"); reviewerData.put("username", "reviewer01"); - redisService.hSetAll(RedisKeyManager.tokenKey(REVIEWER_TOKEN), reviewerData, 3600L); + redisService.hSetAll(RedisUtil.tokenKey(REVIEWER_TOKEN), reviewerData, 3600L); // ANNOTATOR Token:companyId=1, userId=3 Map annotatorData = new HashMap<>(); @@ -93,13 +93,13 @@ public class ShiroFilterIntegrationTest extends AbstractIntegrationTest { annotatorData.put("role", "ANNOTATOR"); annotatorData.put("companyId", "1"); annotatorData.put("username", "annotator01"); - redisService.hSetAll(RedisKeyManager.tokenKey(ANNOTATOR_TOKEN), annotatorData, 3600L); + redisService.hSetAll(RedisUtil.tokenKey(ANNOTATOR_TOKEN), annotatorData, 3600L); } @AfterEach void cleanupTokens() { - redisService.delete(RedisKeyManager.tokenKey(REVIEWER_TOKEN)); - redisService.delete(RedisKeyManager.tokenKey(ANNOTATOR_TOKEN)); + redisService.delete(RedisUtil.tokenKey(REVIEWER_TOKEN)); + redisService.delete(RedisUtil.tokenKey(ANNOTATOR_TOKEN)); } // ------------------------------------------------------------------ 测试用例 -- diff --git a/src/test/java/com/label/integration/SourceIntegrationTest.java b/src/test/java/com/label/integration/SourceIntegrationTest.java index 9e8f0a5..71a8950 100644 --- a/src/test/java/com/label/integration/SourceIntegrationTest.java +++ b/src/test/java/com/label/integration/SourceIntegrationTest.java @@ -2,7 +2,7 @@ package com.label.integration; import com.label.AbstractIntegrationTest; import com.label.service.RedisService; -import com.label.util.RedisKeyManager; +import com.label.util.RedisUtil; import org.junit.jupiter.api.*; import org.springframework.beans.factory.annotation.Autowired; @@ -46,20 +46,20 @@ public class SourceIntegrationTest extends AbstractIntegrationTest { @BeforeEach void setupTokens() { // uploader01 token (userId=4 from init.sql seed) - redisService.hSetAll(RedisKeyManager.tokenKey(UPLOADER_TOKEN), + redisService.hSetAll(RedisUtil.tokenKey(UPLOADER_TOKEN), Map.of("userId", "4", "role", "UPLOADER", "companyId", "1", "username", "uploader01"), 3600L); // admin token (userId=1 from init.sql seed) - redisService.hSetAll(RedisKeyManager.tokenKey(ADMIN_TOKEN), + redisService.hSetAll(RedisUtil.tokenKey(ADMIN_TOKEN), Map.of("userId", "1", "role", "ADMIN", "companyId", "1", "username", "admin"), 3600L); } @AfterEach void cleanupTokens() { - redisService.delete(RedisKeyManager.tokenKey(UPLOADER_TOKEN)); - redisService.delete(RedisKeyManager.tokenKey(UPLOADER2_TOKEN)); - redisService.delete(RedisKeyManager.tokenKey(ADMIN_TOKEN)); + redisService.delete(RedisUtil.tokenKey(UPLOADER_TOKEN)); + redisService.delete(RedisUtil.tokenKey(UPLOADER2_TOKEN)); + redisService.delete(RedisUtil.tokenKey(ADMIN_TOKEN)); } // ------------------------------------------------------------------ 权限测试 -- diff --git a/src/test/java/com/label/integration/SysConfigIntegrationTest.java b/src/test/java/com/label/integration/SysConfigIntegrationTest.java index 55e140d..2eb6984 100644 --- a/src/test/java/com/label/integration/SysConfigIntegrationTest.java +++ b/src/test/java/com/label/integration/SysConfigIntegrationTest.java @@ -2,7 +2,7 @@ package com.label.integration; import com.label.AbstractIntegrationTest; import com.label.service.RedisService; -import com.label.util.RedisKeyManager; +import com.label.util.RedisUtil; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -46,7 +46,7 @@ public class SysConfigIntegrationTest extends AbstractIntegrationTest { "SELECT id FROM sys_user WHERE username = 'admin'", Long.class); // 伪造 Redis Token - redisService.hSetAll(RedisKeyManager.tokenKey(ADMIN_TOKEN), + redisService.hSetAll(RedisUtil.tokenKey(ADMIN_TOKEN), Map.of("userId", adminUserId.toString(), "role", "ADMIN", "companyId", companyId.toString(), "username", "admin"), 3600L); @@ -54,7 +54,7 @@ public class SysConfigIntegrationTest extends AbstractIntegrationTest { @AfterEach void cleanupTokens() { - redisService.delete(RedisKeyManager.tokenKey(ADMIN_TOKEN)); + redisService.delete(RedisUtil.tokenKey(ADMIN_TOKEN)); } // ------------------------------------------------------------------ 测试 1: 公司配置覆盖全局 -- diff --git a/src/test/java/com/label/integration/TaskClaimConcurrencyTest.java b/src/test/java/com/label/integration/TaskClaimConcurrencyTest.java index c958031..cbfbb77 100644 --- a/src/test/java/com/label/integration/TaskClaimConcurrencyTest.java +++ b/src/test/java/com/label/integration/TaskClaimConcurrencyTest.java @@ -2,7 +2,7 @@ package com.label.integration; import com.label.AbstractIntegrationTest; import com.label.service.RedisService; -import com.label.util.RedisKeyManager; +import com.label.util.RedisUtil; import org.junit.jupiter.api.*; import org.springframework.beans.factory.annotation.Autowired; @@ -61,7 +61,7 @@ public class TaskClaimConcurrencyTest extends AbstractIntegrationTest { tokens.add(token); // 所有 Token 使用 userId=3(annotator01),这在真实场景不会发生 // 但在测试中用于验证并发锁机制(redis key 基于 taskId,不是 userId) - redisService.hSetAll(RedisKeyManager.tokenKey(token), + redisService.hSetAll(RedisUtil.tokenKey(token), Map.of("userId", String.valueOf(i + 100), // 假设 userId > 100 不存在,但不影响锁逻辑 "role", "ANNOTATOR", "companyId", "1", "username", "annotator" + i), 3600L); @@ -70,9 +70,9 @@ public class TaskClaimConcurrencyTest extends AbstractIntegrationTest { @AfterEach void cleanup() { - tokens.forEach(token -> redisService.delete(RedisKeyManager.tokenKey(token))); + tokens.forEach(token -> redisService.delete(RedisUtil.tokenKey(token))); if (taskId != null) { - redisService.delete(RedisKeyManager.taskClaimKey(taskId)); + redisService.delete(RedisUtil.taskClaimKey(taskId)); } } diff --git a/src/test/java/com/label/integration/VideoCallbackIdempotencyTest.java b/src/test/java/com/label/integration/VideoCallbackIdempotencyTest.java index 2fd05c7..8cc07ff 100644 --- a/src/test/java/com/label/integration/VideoCallbackIdempotencyTest.java +++ b/src/test/java/com/label/integration/VideoCallbackIdempotencyTest.java @@ -2,7 +2,7 @@ package com.label.integration; import com.label.AbstractIntegrationTest; import com.label.service.RedisService; -import com.label.util.RedisKeyManager; +import com.label.util.RedisUtil; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -46,7 +46,7 @@ public class VideoCallbackIdempotencyTest extends AbstractIntegrationTest { "SELECT id FROM sys_user WHERE username = 'admin'", Long.class); // 伪造 Redis Token - redisService.hSetAll(RedisKeyManager.tokenKey(ADMIN_TOKEN), + redisService.hSetAll(RedisUtil.tokenKey(ADMIN_TOKEN), Map.of("userId", adminUserId.toString(), "role", "ADMIN", "companyId", companyId.toString(), "username", "admin"), 3600L); @@ -72,7 +72,7 @@ public class VideoCallbackIdempotencyTest extends AbstractIntegrationTest { @AfterEach void cleanupTokens() { - redisService.delete(RedisKeyManager.tokenKey(ADMIN_TOKEN)); + redisService.delete(RedisUtil.tokenKey(ADMIN_TOKEN)); } // ------------------------------------------------------------------ 测试 1: 幂等性 -- diff --git a/src/test/java/com/label/unit/TokenFilterTest.java b/src/test/java/com/label/unit/TokenFilterTest.java index 97ce341..2098f64 100644 --- a/src/test/java/com/label/unit/TokenFilterTest.java +++ b/src/test/java/com/label/unit/TokenFilterTest.java @@ -7,7 +7,7 @@ import com.label.common.shiro.TokenPrincipal; import com.label.common.shiro.UserRealm; import com.label.config.ShiroConfig; import com.label.service.RedisService; -import com.label.util.RedisKeyManager; +import com.label.util.RedisUtil; import org.apache.shiro.SecurityUtils; import org.apache.shiro.mgt.DefaultSecurityManager; @@ -56,7 +56,7 @@ class TokenFilterTest { ReflectionTestUtils.setField(filter, "authEnabled", true); ReflectionTestUtils.setField(filter, "tokenTtlSeconds", 7200L); String token = "valid-token"; - when(redisService.hGetAll(RedisKeyManager.tokenKey(token))).thenReturn(Map.of( + when(redisService.hGetAll(RedisUtil.tokenKey(token))).thenReturn(Map.of( "userId", "10", "role", "ADMIN", "companyId", "20", @@ -73,7 +73,7 @@ class TokenFilterTest { assertThat(response.getStatus()).isEqualTo(200); assertThat(chain.principal).isInstanceOf(TokenPrincipal.class); assertThat(chain.roleChecked).isTrue(); - verify(redisService).expire(RedisKeyManager.tokenKey(token), 7200L); + verify(redisService).expire(RedisUtil.tokenKey(token), 7200L); } @Test