From d448c524b786b882bfc04fccae4d6a2d6067b500 Mon Sep 17 00:00:00 2001 From: Hanserwei Date: Thu, 2 Oct 2025 22:27:49 +0800 Subject: [PATCH] =?UTF-8?q?feat(auth):=20=E6=96=B0=E5=A2=9E=E7=94=A8?= =?UTF-8?q?=E6=88=B7ID=E4=B8=8A=E4=B8=8B=E6=96=87=E8=BF=87=E6=BB=A4?= =?UTF-8?q?=E5=99=A8=E5=8F=8A=E7=99=BB=E5=87=BA=E9=80=BB=E8=BE=91=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 GlobalConstants 常量类定义 USER_ID 常量 - 新增 HeaderUserId2ContextFilter 过滤器从请求头获取用户 ID 并存入 ThreadLocal - 新增 LoginUserContextHolder 工具类用于管理用户 ID 的 ThreadLocal 操作 -优化 UserController 的 logout 方法,移除手动传参 userId,改为从上下文获取 - 优化 UserServiceImpl 的 logout 方法实现,通过上下文获取用户 ID 完成登出 - 在 han-note-gateway 模块中添加 tomcat-embed-core依赖以支持相关功能 --- .../auth/controller/UserController.java | 6 +-- .../filter/HeaderUserId2ContextFilter.java | 47 +++++++++++++++++++ .../auth/filter/LoginUserContextHolder.java | 45 ++++++++++++++++++ .../hannote/auth/service/UserService.java | 2 +- .../auth/service/impl/UserServiceImpl.java | 4 +- han-note-gateway/pom.xml | 4 ++ .../common/constant/GlobalConstants.java | 10 ++++ 7 files changed, 112 insertions(+), 6 deletions(-) create mode 100644 han-note-auth/src/main/java/com/hanserwei/hannote/auth/filter/HeaderUserId2ContextFilter.java create mode 100644 han-note-auth/src/main/java/com/hanserwei/hannote/auth/filter/LoginUserContextHolder.java create mode 100644 hanserwei-framework/hanserwei-common/src/main/java/com/hanserwei/framework/common/constant/GlobalConstants.java diff --git a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/controller/UserController.java b/han-note-auth/src/main/java/com/hanserwei/hannote/auth/controller/UserController.java index de68b86..3ca8fcc 100644 --- a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/controller/UserController.java +++ b/han-note-auth/src/main/java/com/hanserwei/hannote/auth/controller/UserController.java @@ -27,9 +27,7 @@ public class UserController { @PostMapping("/logout") @ApiOperationLog(description = "账号登出") - public Response logout(@RequestHeader("userId") String userId) { - log.info("==> 网关透传过来的用户 ID: {}", userId); - Long userIdLong = Long.parseLong(userId); - return userService.logout(userIdLong); + public Response logout() { + return userService.logout(); } } diff --git a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/filter/HeaderUserId2ContextFilter.java b/han-note-auth/src/main/java/com/hanserwei/hannote/auth/filter/HeaderUserId2ContextFilter.java new file mode 100644 index 0000000..68cef3c --- /dev/null +++ b/han-note-auth/src/main/java/com/hanserwei/hannote/auth/filter/HeaderUserId2ContextFilter.java @@ -0,0 +1,47 @@ +package com.hanserwei.hannote.auth.filter; + +import com.hanserwei.framework.common.constant.GlobalConstants; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +import java.io.IOException; + +@Component +@Slf4j +public class HeaderUserId2ContextFilter extends OncePerRequestFilter { + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, + FilterChain chain) throws ServletException, IOException { + + // 从请求头中获取用户 ID + String userId = request.getHeader(GlobalConstants.USER_ID); + + log.info("## HeaderUserId2ContextFilter, 用户 ID: {}", userId); + + // 判断请求头中是否存在用户 ID + if (StringUtils.isBlank(userId)) { + // 若为空,则直接放行 + chain.doFilter(request, response); + return; + } + + // 如果 header 中存在 userId,则设置到 ThreadLocal 中 + log.info("===== 设置 userId 到 ThreadLocal 中, 用户 ID: {}", userId); + LoginUserContextHolder.setUserId(userId); + + try { + chain.doFilter(request, response); + } finally { + // 一定要删除 ThreadLocal ,防止内存泄露 + LoginUserContextHolder.remove(); + log.info("===== 删除 ThreadLocal, userId: {}", userId); + } + } +} \ No newline at end of file diff --git a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/filter/LoginUserContextHolder.java b/han-note-auth/src/main/java/com/hanserwei/hannote/auth/filter/LoginUserContextHolder.java new file mode 100644 index 0000000..f08b414 --- /dev/null +++ b/han-note-auth/src/main/java/com/hanserwei/hannote/auth/filter/LoginUserContextHolder.java @@ -0,0 +1,45 @@ +package com.hanserwei.hannote.auth.filter; + +import com.hanserwei.framework.common.constant.GlobalConstants; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +public class LoginUserContextHolder { + + // 初始化一个 ThreadLocal 变量 + private static final ThreadLocal> LOGIN_USER_CONTEXT_THREAD_LOCAL + = ThreadLocal.withInitial(HashMap::new); + + + /** + * 设置用户 ID + * + * @param value 用户 ID + */ + public static void setUserId(Object value) { + LOGIN_USER_CONTEXT_THREAD_LOCAL.get().put(GlobalConstants.USER_ID, value); + } + + /** + * 获取用户 ID + * + * @return 用户 ID + */ + public static Long getUserId() { + Object value = LOGIN_USER_CONTEXT_THREAD_LOCAL.get().get(GlobalConstants.USER_ID); + if (Objects.isNull(value)) { + return null; + } + return Long.valueOf(value.toString()); + } + + /** + * 删除 ThreadLocal + */ + public static void remove() { + LOGIN_USER_CONTEXT_THREAD_LOCAL.remove(); + } + +} \ No newline at end of file diff --git a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/service/UserService.java b/han-note-auth/src/main/java/com/hanserwei/hannote/auth/service/UserService.java index b0e3b9c..40b9a48 100644 --- a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/service/UserService.java +++ b/han-note-auth/src/main/java/com/hanserwei/hannote/auth/service/UserService.java @@ -19,5 +19,5 @@ public interface UserService extends IService { * 退出登录 * @return 响应结果 */ - Response logout(Long userId); + Response logout(); } diff --git a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/service/impl/UserServiceImpl.java b/han-note-auth/src/main/java/com/hanserwei/hannote/auth/service/impl/UserServiceImpl.java index f5a80ec..2838e5d 100644 --- a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/service/impl/UserServiceImpl.java +++ b/han-note-auth/src/main/java/com/hanserwei/hannote/auth/service/impl/UserServiceImpl.java @@ -21,6 +21,7 @@ import com.hanserwei.hannote.auth.domain.mapper.UserDOMapper; import com.hanserwei.hannote.auth.domain.mapper.UserRoleDOMapper; import com.hanserwei.hannote.auth.enums.LoginTypeEnum; import com.hanserwei.hannote.auth.enums.ResponseCodeEnum; +import com.hanserwei.hannote.auth.filter.LoginUserContextHolder; import com.hanserwei.hannote.auth.model.vo.user.UserLoginReqVO; import com.hanserwei.hannote.auth.service.UserService; import lombok.RequiredArgsConstructor; @@ -144,7 +145,8 @@ public class UserServiceImpl extends ServiceImpl implement } @Override - public Response logout(Long userId) { + public Response logout() { + Long userId = LoginUserContextHolder.getUserId(); StpUtil.logout(userId); return Response.success(); } diff --git a/han-note-gateway/pom.xml b/han-note-gateway/pom.xml index 4a3de0b..bf694a8 100644 --- a/han-note-gateway/pom.xml +++ b/han-note-gateway/pom.xml @@ -64,6 +64,10 @@ com.hanserwei hanserwei-spring-boot-starter-jackson + + org.apache.tomcat.embed + tomcat-embed-core + diff --git a/hanserwei-framework/hanserwei-common/src/main/java/com/hanserwei/framework/common/constant/GlobalConstants.java b/hanserwei-framework/hanserwei-common/src/main/java/com/hanserwei/framework/common/constant/GlobalConstants.java new file mode 100644 index 0000000..72f3b6a --- /dev/null +++ b/hanserwei-framework/hanserwei-common/src/main/java/com/hanserwei/framework/common/constant/GlobalConstants.java @@ -0,0 +1,10 @@ +package com.hanserwei.framework.common.constant; + +public interface GlobalConstants { + + /** + * 用户 ID + */ + String USER_ID = "userId"; +} +