添加了重生成token
Change-Id: I82a372b10cabf1acea6014d8ce9f3b960ef5245a
diff --git a/pom.xml b/pom.xml
index 9238ad6..39255c6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -100,6 +100,11 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.springframework.security</groupId>
+ <artifactId>spring-security-test</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
diff --git a/src/main/java/com/example/g8backend/controller/AuthController.java b/src/main/java/com/example/g8backend/controller/AuthController.java
index 48376f2..bb6c0a9 100644
--- a/src/main/java/com/example/g8backend/controller/AuthController.java
+++ b/src/main/java/com/example/g8backend/controller/AuthController.java
@@ -10,9 +10,10 @@
import com.example.g8backend.util.mailUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
-
+import jakarta.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@@ -111,4 +112,19 @@
Object value = redisTemplate.opsForValue().get("test");
return ApiResponse.success("test redis ok");
}
+
+ //刷新token
+ @PostMapping("/refresh-token")
+ public ApiResponse<String> refreshToken(HttpServletRequest request) {
+ Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
+ if (!(principal instanceof Long userId)) {
+ return ApiResponse.error(401, "未认证,无法刷新token");
+ }
+ String oldToken = request.getHeader("Authorization");
+ if (oldToken != null && oldToken.startsWith("Bearer ")) {
+ oldToken = oldToken.substring(7);
+ }
+ String newToken = jwtUtil.generateToken(userId);
+ return ApiResponse.success("Token刷新成功", newToken);
+ }
}
diff --git a/src/main/java/com/example/g8backend/dto/ApiResponse.java b/src/main/java/com/example/g8backend/dto/ApiResponse.java
index 8ad28f7..9940361 100644
--- a/src/main/java/com/example/g8backend/dto/ApiResponse.java
+++ b/src/main/java/com/example/g8backend/dto/ApiResponse.java
@@ -1,12 +1,15 @@
package com.example.g8backend.dto;
+import lombok.Data;
+
+@Data
public class ApiResponse<T> {
private int code;
private String message;
private T data;
public ApiResponse() {}
-
+
public ApiResponse(int code, String message, T data) {
this.code = code;
this.message = message;
diff --git a/src/test/java/com/example/g8backend/service/AuthControllerTest.java b/src/test/java/com/example/g8backend/service/AuthControllerTest.java
new file mode 100644
index 0000000..7dbf524
--- /dev/null
+++ b/src/test/java/com/example/g8backend/service/AuthControllerTest.java
@@ -0,0 +1,86 @@
+package com.example.g8backend.service;
+
+import com.example.g8backend.controller.AuthController;
+import com.example.g8backend.util.JwtUtil;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.test.web.servlet.MockMvc;
+
+import static org.mockito.Mockito.*;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
+
+@WebMvcTest(AuthController.class)
+@AutoConfigureMockMvc(addFilters = false) // 关键:禁用Security过滤器
+class AuthControllerTest {
+
+ @Autowired
+ private MockMvc mockMvc;
+
+ // 为所有依赖的 Bean 添加 Mock
+ @MockBean
+ private com.example.g8backend.service.IUserService userService;
+ @MockBean
+ private com.example.g8backend.service.IUserStatsService userStatsService;
+ @MockBean
+ private com.example.g8backend.util.mailUtil mailUtil;
+ @MockBean
+ private org.springframework.security.crypto.password.PasswordEncoder passwordEncoder;
+ @MockBean
+ private JwtUtil jwtUtil;
+ @MockBean
+ private org.springframework.data.redis.core.RedisTemplate<String, Object> redisTemplate;
+
+ @BeforeEach
+ void setUp() {
+ // 默认设置为已认证用户
+ Authentication authentication = mock(Authentication.class);
+ when(authentication.getPrincipal()).thenReturn(123L);
+ SecurityContext securityContext = mock(SecurityContext.class);
+ when(securityContext.getAuthentication()).thenReturn(authentication);
+ SecurityContextHolder.setContext(securityContext);
+ }
+
+ @Test
+ @DisplayName("刷新token-认证通过返回新token")
+ void refreshToken_ShouldReturnNewToken() throws Exception {
+ String newToken = "new.jwt.token";
+ when(jwtUtil.generateToken(123L)).thenReturn(newToken);
+
+ mockMvc.perform(post("/auth/refresh-token")
+ .header("Authorization", "Bearer old.jwt.token")
+ .with(csrf())
+ .accept("application/json")) // 加上这一行
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$.code").value(200))
+ .andExpect(jsonPath("$.message").value("Token刷新成功"))
+ .andExpect(jsonPath("$.data").value(newToken));
+ }
+
+ @Test
+ @DisplayName("刷新token-未认证返回401")
+ void refreshToken_Unauthenticated_ShouldReturn401() throws Exception {
+ // 设置为未认证
+ Authentication authentication = mock(Authentication.class);
+ when(authentication.getPrincipal()).thenReturn("anonymousUser");
+ SecurityContext securityContext = mock(SecurityContext.class);
+ when(securityContext.getAuthentication()).thenReturn(authentication);
+ SecurityContextHolder.setContext(securityContext);
+
+ mockMvc.perform(post("/auth/refresh-token")
+ .with(csrf())
+ .accept("application/json")) // 加上这一行
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$.code").value(401))
+ .andExpect(jsonPath("$.message").value("未认证,无法刷新token"));
+ }
+}
\ No newline at end of file