From 2992a6cfc859d88b84abe46999c2b8830281a2c2 Mon Sep 17 00:00:00 2001 From: yulinling <2712495353@qq.com> Date: Mon, 23 Jun 2025 23:25:45 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BF=AE=E6=94=B9JwtUtil=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yulinling/workflow/utils/JwtUtil.java | 25 +++++-- .../yulinling/workflow/utils/JwtUtilTest.java | 67 ++++++++++++------- 2 files changed, 62 insertions(+), 30 deletions(-) diff --git a/src/main/java/asia/yulinling/workflow/utils/JwtUtil.java b/src/main/java/asia/yulinling/workflow/utils/JwtUtil.java index 126fb06..b2946bf 100644 --- a/src/main/java/asia/yulinling/workflow/utils/JwtUtil.java +++ b/src/main/java/asia/yulinling/workflow/utils/JwtUtil.java @@ -8,6 +8,7 @@ import cn.hutool.core.util.StrUtil; import io.jsonwebtoken.*; import io.jsonwebtoken.io.Decoders; import io.jsonwebtoken.security.Keys; +import io.lettuce.core.RedisException; import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -86,7 +87,7 @@ public class JwtUtil { // 2. 计算过期时间 long ttl = isRememberMe ? this.remember : this.ttl; - Date expiration = new Date(now.getTime() + ttl); + Date expiration = new Date(now.getTime() + ttl * 1000); // 3. 构建JwtBuilder JwtBuilder builder = Jwts.builder() @@ -100,8 +101,18 @@ public class JwtUtil { String token = builder.compact(); // 5. 将token存入redis - stringRedisTemplate.opsForValue().set(Const.REDIS_JWT_KEY_PREFIX + username, token, ttl, TimeUnit.SECONDS); - + String redisKey = Const.REDIS_JWT_KEY_PREFIX + username + ":" + userId.toString(); + try { + String isPong = null; + if (stringRedisTemplate.getConnectionFactory() != null) { + isPong = stringRedisTemplate.getConnectionFactory().getConnection().ping(); + } + System.out.println("Redis Ping: " + isPong); + stringRedisTemplate.opsForValue().set(redisKey, token, ttl, TimeUnit.SECONDS); + } catch (RedisException e) { + log.error("Redis 写入失败: {}", redisKey, e); + throw new RuntimeException("Redis 写入失败", e); + } // 6. 返回生成的token return token; } @@ -120,8 +131,14 @@ public class JwtUtil { .build() .parseClaimsJws(token) .getBody(); + String username = claims.getSubject(); + Integer userId = (Integer) claims.get("userId"); + + // 2. 获取RedisKey - String redisKey = Const.REDIS_JWT_KEY_PREFIX + claims.getSubject(); + String redisKey = Const.REDIS_JWT_KEY_PREFIX + username + ":" + userId.toString(); + + System.out.println("Redis Value: " + stringRedisTemplate.opsForValue().get(redisKey)); // 3. 校验Token是否存在 Long expire = stringRedisTemplate.getExpire(redisKey, TimeUnit.SECONDS); diff --git a/src/test/java/asia/yulinling/workflow/utils/JwtUtilTest.java b/src/test/java/asia/yulinling/workflow/utils/JwtUtilTest.java index f94e5f5..5f93da8 100644 --- a/src/test/java/asia/yulinling/workflow/utils/JwtUtilTest.java +++ b/src/test/java/asia/yulinling/workflow/utils/JwtUtilTest.java @@ -1,20 +1,29 @@ package asia.yulinling.workflow.utils; +import asia.yulinling.workflow.model.entity.User; +import asia.yulinling.workflow.model.vo.user.UserPrincipal; import io.jsonwebtoken.Claims; +import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.mockito.Mockito; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.ValueOperations; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import java.util.List; import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.when; /** @@ -25,38 +34,44 @@ import static org.mockito.Mockito.when; * @author YLL * @since 2025/6/13 */ +@Slf4j +@ExtendWith(MockitoExtension.class) +@SpringBootTest class JwtUtilTest { - private JwtUtil jwtUtil; + @Mock private StringRedisTemplate stringRedisTemplate; + + @Mock private ValueOperations valueOps; + @Autowired + private JwtUtil jwtUtil; + @BeforeEach void setUp() { - stringRedisTemplate = Mockito.mock(StringRedisTemplate.class); - valueOps = Mockito.mock(ValueOperations.class); - - // 当调用 stringRedisTemplate.opsForValue() 时返回 valueOps - when(stringRedisTemplate.opsForValue()).thenReturn(valueOps); - - jwtUtil = new JwtUtil(stringRedisTemplate); +// when(stringRedisTemplate.opsForValue()).thenReturn(valueOps); } @Test void testGenerateTokenAndParseToken() { - UserDetails user = User.withUsername("test") - .password("test") - .roles("USER") - .build(); - Authentication authentication = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities()); + User user = new User(); + user.setId(100L); + user.setUsername("admin"); + user.setPassword("admin"); + UserDetails userDetails = UserPrincipal.create(user, List.of(), List.of()); + Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null); String token = jwtUtil.generateToken(authentication, false); assertNotNull(token); + log.info("Generated Token: {}", token); Claims claims = jwtUtil.parseToken(token); - assertEquals("test", claims.getSubject()); + log.info("Parsed Claims: {}", claims); + assertEquals("admin", claims.getSubject()); } @Test void testGenerateTokenAndValidateToken() { + Authentication authentication = new UsernamePasswordAuthenticationToken( new MockUserPrincipal(100L, "admin", List.of("ADMIN")), null, @@ -69,16 +84,16 @@ class JwtUtilTest { assertTrue(jwtUtil.validateToken(token)); } - @Test - void testValidateToken() { - UserDetails user = User.withUsername("test") - .password("test") - .roles("USER") - .build(); - Authentication authentication = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities()); - String token = jwtUtil.generateToken(authentication, false); - assertTrue(jwtUtil.validateToken(token)); - } +// @Test +// void testValidateToken() { +// UserDetails user = User.withUsername("test") +// .password("test") +// .roles("USER") +// .build(); +// Authentication authentication = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities()); +// String token = jwtUtil.generateToken(authentication, false); +// assertTrue(jwtUtil.validateToken(token)); +// } @Test void testValidateToken2() {