spring boot 8

一、登录认证拦截器实现

1. 核心目标

  • 所有接口统一校验 Authorization 请求头中的 JWT 令牌
  • 放行 /user/login/user/register 接口,无需令牌即可访问

2. 拦截器代码(LoginInterceptor.java

java

运行

复制代码
@Component
public class LoginInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 1. 获取请求头中的令牌
        String token = request.getHeader("Authorization");
        try {
            // 2. 解析并验证令牌
            Map<String, Object> claims = JwtUtil.parseToken(token);
            // 3. 将用户信息存入 ThreadLocal,供后续业务使用
            ThreadLocalUtil.set(claims);
            // 4. 校验通过,放行请求
            return true;
        } catch (Exception e) {
            // 令牌无效/过期,设置响应状态码并拒绝请求
            response.setStatus(401);
            return false;
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 请求结束后,清除 ThreadLocal 数据,防止内存泄漏
        ThreadLocalUtil.remove();
    }
}

3. 注册拦截器(WebConfig.java

java

运行

复制代码
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private LoginInterceptor loginInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor)
                // 拦截所有请求
                .addPathPatterns("/**")
                // 放行登录、注册接口
                .excludePathPatterns("/user/login", "/user/register");
    }
}

二、ThreadLocal 工具类实现

1. 核心作用

  • 提供线程局部变量,同一请求的所有层级(Controller/Service/Mapper)都能安全访问用户信息
  • 线程安全,用完必须调用 remove() 释放数据,避免内存泄漏

2. 工具类代码(ThreadLocalUtil.java

java

运行

复制代码
public class ThreadLocalUtil {
    // 提供 ThreadLocal 对象
    private static final ThreadLocal THREAD_LOCAL = new ThreadLocal();

    // 根据键获取值
    public static <T> T get() {
        return (T) THREAD_LOCAL.get();
    }

    // 存储键值对
    public static void set(Object value) {
        THREAD_LOCAL.set(value);
    }

    // 清除 ThreadLocal,防止内存泄漏
    public static void remove() {
        THREAD_LOCAL.remove();
    }
}

三、业务接口改造(获取用户信息)

1. Controller 层接口

java

运行

复制代码
@GetMapping("/userInfo")
public Result<User> userInfo() {
    // 从 ThreadLocal 中获取解析后的用户信息
    Map<String, Object> claims = ThreadLocalUtil.get();
    String username = (String) claims.get("username");
    
    // 调用 Service 查询用户信息
    User user = userService.findByUsername(username);
    return Result.success(user);
}

2. 复用 Service & Mapper 层

  • UserService.findByUsername(username):直接复用注册 / 登录时的查询方法
  • UserMapper.select * from user where username = ?:复用已有的查询 SQL

四、关键注意事项

  1. 拦截器放行配置/user/login/user/register 必须放行,否则用户无法登录获取令牌
  2. ThreadLocal 内存泄漏 :请求结束后必须调用 remove(),否则 Tomcat 线程复用会导致数据混乱
  3. 令牌校验失败处理 :拦截器中校验失败直接返回 401 状态码,前端可据此跳转登录页
  4. 请求头名称统一 :前后端约定令牌都放在 Authorization 请求头中,避免出现字段名不一致的问题

五、完整流程总结

  1. 用户登录成功,后端生成 JWT 令牌返回给前端
  2. 前端后续请求携带令牌,请求头 Authorization: 令牌
  3. LoginInterceptor 拦截请求,解析验证令牌,将用户信息存入 ThreadLocal
  4. 业务接口从 ThreadLocal 中获取用户信息,完成后续操作
  5. 请求结束,afterCompletion 中清除 ThreadLocal 数据
相关推荐
咖啡八杯1 小时前
GoF设计模式——解释器模式
java·后端·spring·设计模式
优橙教育1 小时前
5G网优培训 vs Java开发:转行选哪个?
java·开发语言·5g
糖果店的幽灵2 小时前
【DeepAgents 从入门到精通】Context Management 上下文管理
java·人工智能·后端·spring·中间件·langgraph·deepagents
腻害兔3 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:字典、短信、邮件、通知——后台系统的“基础设施四件套“!
java·前端·vue.js·产品经理·ai编程
SeaTunnel3 小时前
从 Python Script 地狱到标准化数据集成框架
大数据·开发语言·python·程序员·代码·seatunnel
碎光拾影4 小时前
ARM交叉工具链各工具作用及IMX6ULL平台LED+蜂鸣器裸机程序实现
java·开发语言·数据库
Marst Code4 小时前
(python)2026Plotly 库评估:交互式可视化到底值不值得引入?
开发语言·python
Miao121314 小时前
微服务 API 测试实践:海外某民宿平台如何构建模式驱动测试基础设施
java·开发语言
腻害兔5 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:支付模块 yudao-module-pay,一个让产品经理都看懂的支付中台设计
java·前端·vue.js·产品经理·ai编程
CRMEB系统商城6 小时前
开源自建还是SaaS订阅?算一笔3年经济账
java·大数据·开发语言·开源