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 数据
相关推荐
名字还没想好☜5 小时前
Python f-string 进阶:数字格式化、对齐填充、调试 = 号与嵌套表达式
开发语言·数据库·python·字符串格式化·f-string
·薯条大王6 小时前
经济实惠玩云服务器|一台云服务器多人共用,子账号配置教程
java·linux·运维·服务器·汇编·c++·python
一壶浊酒..8 小时前
Scrape Webpack练习
开发语言·javascript·webpack
ZJH__GO9 小时前
网络编程v4pro--实现聊天室文件传输功能
java·服务器·网络·计算机网络
程序员黑豆9 小时前
Windows 系统 Java 环境变量配置全攻略:解决“不是内部或外部命令”
java·前端·ai编程
命运之光9 小时前
【C语言完整代码】就诊信息管理系统
java·c语言·开发语言
凤山老林9 小时前
Spring Boot @Async 线上实战:从默认配置到生产级线程池治理
java·spring boot·后端
命运之光9 小时前
【C语言完整代码】图书管理系统:图书馆场景下的增删改查实战
c语言·开发语言
猿长大人10 小时前
C# | Serilog 新手入门
开发语言·c#·.net·log
marvelyu10 小时前
每天10分钟学会OceanBase系列(Day 20):跨机房容灾实战——构建多数据中心高可用架构
java·大数据·数据库