【微服务】记录-登录信息传递过程

发布于:2025-07-05 ⋅ 阅读:(15) ⋅ 点赞:(0)

在这里插入图片描述
开发业务的时候,只需要在通过UserContext提供的getUser()方法就可以拿到用户id了
在这个拦截器中,获取到用户信息后保存到了UserContext中,这是一个基于ThreadLocal的工具,可以确保不同的请求之间互不干扰,避免线程安全问题发生:

public class UserContext {
    private static final ThreadLocal<Long> TL = new ThreadLocal<>();

    /**
     * 保存用户信息
     * @param userId 用户id
     */
    public static void setUser(Long userId){
        TL.set(userId);
    }

    /**
     * 获取用户
     * @return 用户id
     */
    public static Long getUser(){
        return TL.get();
    }

    /**
     * 移除用户信息
     */
    public static void removeUser(){
        TL.remove();
    }
}

然后是微服务中的获取请求头中的用户信息的拦截器。由于这个拦截器在每个微服务中都需要,与其重复编写,不如抽取到一个模块中。

public class UserInfoInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 1.尝试获取头信息中的用户信息
        String authorization = request.getHeader(JwtConstants.USER_HEADER);
        // 2.判断是否为空
        if (authorization == null) {
            return true;
        }
        // 3.转为用户id并保存
        try {
            Long userId = Long.valueOf(authorization);
            UserContext.setUser(userId);
            return true;
        } catch (NumberFormatException e) {
            log.error("用户身份信息格式不正确,{}, 原因:{}", authorization, e.getMessage());
            return true;
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 清理用户信息
        UserContext.removeUser();
    }
}