feat(auth): 新增用户ID上下文过滤器及登出逻辑优化
- 新增 GlobalConstants 常量类定义 USER_ID 常量 - 新增 HeaderUserId2ContextFilter 过滤器从请求头获取用户 ID 并存入 ThreadLocal - 新增 LoginUserContextHolder 工具类用于管理用户 ID 的 ThreadLocal 操作 -优化 UserController 的 logout 方法,移除手动传参 userId,改为从上下文获取 - 优化 UserServiceImpl 的 logout 方法实现,通过上下文获取用户 ID 完成登出 - 在 han-note-gateway 模块中添加 tomcat-embed-core依赖以支持相关功能
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<Map<String, Object>> 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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,5 +19,5 @@ public interface UserService extends IService<UserDO> {
|
||||
* 退出登录
|
||||
* @return 响应结果
|
||||
*/
|
||||
Response<?> logout(Long userId);
|
||||
Response<?> logout();
|
||||
}
|
||||
|
||||
@@ -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<UserDOMapper, UserDO> implement
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response<?> logout(Long userId) {
|
||||
public Response<?> logout() {
|
||||
Long userId = LoginUserContextHolder.getUserId();
|
||||
StpUtil.logout(userId);
|
||||
return Response.success();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user