当前位置: 首页 > article >正文

Spring Boot 中实现全局 Token 验证的两种方式

文章目录

      • 学习文章:Spring Boot 中实现全局 Token 验证的两种方式
    • 一、为什么需要全局 Token 验证?
    • 二、使用拦截器实现全局 Token 验证
      • 1. 创建 Token 验证拦截器
      • 2. 注册拦截器
      • 3. 测试拦截器
    • 三、使用过滤器实现全局 Token 验证
      • 1. 创建 Token 验证过滤器
      • 2. 注册过滤器
      • 3. 测试过滤器
    • 四、拦截器 vs 过滤器
      • 1. **拦截器的优势**
      • 2. **过滤器的优势**
      • 3. **选择建议**
    • 五、全局异常处理
      • 1. 定义统一响应格式
      • 2. 全局异常处理器
      • 3. 在拦截器或过滤器中抛出异常
    • 六、总结


学习文章:Spring Boot 中实现全局 Token 验证的两种方式

在 Spring Boot 项目中,Token 验证是保护接口安全的常见手段。如果每个接口都单独编写 Token 验证逻辑,会导致代码冗余且难以维护。为了解决这个问题,可以通过 拦截器(Interceptor)过滤器(Filter) 实现全局 Token 验证,从而统一处理所有接口的验证逻辑。

本文将详细介绍如何使用拦截器和过滤器实现全局 Token 验证,并提供完整的代码示例和最佳实践。


一、为什么需要全局 Token 验证?

在前后端分离的架构中,客户端通常通过 Token 进行身份验证。如果每个接口都单独验证 Token,会导致以下问题:

  1. 代码冗余:每个接口都需要编写重复的验证逻辑。
  2. 维护困难:当验证逻辑需要修改时,需要修改所有相关接口。
  3. 容易遗漏:新增接口时可能会忘记添加验证逻辑,导致安全漏洞。

通过全局 Token 验证,可以统一处理所有接口的验证逻辑,提高代码的复用性和可维护性。


二、使用拦截器实现全局 Token 验证

拦截器是 Spring MVC 提供的一种机制,可以在请求到达控制器之前或之后执行特定的逻辑。以下是实现步骤:

1. 创建 Token 验证拦截器

创建一个拦截器类,实现 HandlerInterceptor 接口,并在 preHandle 方法中编写 Token 验证逻辑。

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class TokenInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 从请求头中获取 Token
        String token = request.getHeader("Authorization");

        // 验证 Token
        if (token == null || !isValidToken(token)) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // 401 未授权
            response.getWriter().write("Token 无效或未提供");
            return false; // 中断请求
        }

        return true; // 继续执行请求
    }

    // 模拟 Token 验证逻辑
    private boolean isValidToken(String token) {
        // 这里可以调用具体的 Token 验证服务
        return "valid-token".equals(token);
    }
}

2. 注册拦截器

将拦截器注册到 Spring MVC 中,并配置需要拦截的路径。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private TokenInterceptor tokenInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 拦截所有路径
        registry.addInterceptor(tokenInterceptor)
                .addPathPatterns("/**") // 拦截所有接口
                .excludePathPatterns("/login", "/register"); // 排除不需要拦截的路径
    }
}

3. 测试拦截器

启动项目后,访问任意接口时,如果请求头中没有提供有效的 Token,则会返回 401 错误。


三、使用过滤器实现全局 Token 验证

过滤器是 Servlet 提供的一种机制,可以在请求到达 Spring MVC 之前执行逻辑。以下是实现步骤:

1. 创建 Token 验证过滤器

创建一个过滤器类,实现 Filter 接口,并在 doFilter 方法中编写 Token 验证逻辑。

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class TokenFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;

        // 从请求头中获取 Token
        String token = httpRequest.getHeader("Authorization");

        // 验证 Token
        if (token == null || !isValidToken(token)) {
            httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // 401 未授权
            httpResponse.getWriter().write("Token 无效或未提供");
            return; // 中断请求
        }

        chain.doFilter(request, response); // 继续执行请求
    }

    // 模拟 Token 验证逻辑
    private boolean isValidToken(String token) {
        // 这里可以调用具体的 Token 验证服务
        return "valid-token".equals(token);
    }
}

2. 注册过滤器

将过滤器注册到 Spring Boot 中,并配置需要拦截的路径。

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean<TokenFilter> tokenFilter() {
        FilterRegistrationBean<TokenFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new TokenFilter());
        registrationBean.addUrlPatterns("/*"); // 拦截所有路径
        registrationBean.setOrder(1); // 设置过滤器顺序
        return registrationBean;
    }
}

3. 测试过滤器

启动项目后,访问任意接口时,如果请求头中没有提供有效的 Token,则会返回 401 错误。


四、拦截器 vs 过滤器

1. 拦截器的优势

  • 与 Spring MVC 深度集成,可以访问 Spring 的上下文和 Bean。
  • 可以精确控制拦截的路径(通过 addPathPatternsexcludePathPatterns)。
  • 适合处理与业务逻辑相关的拦截(如权限验证、日志记录)。

2. 过滤器的优势

  • 更底层,可以拦截所有请求(包括静态资源)。
  • 适合处理与 Servlet 相关的逻辑(如编码设置、跨域处理)。

3. 选择建议

  • 如果需要在 Spring MVC 的上下文中处理逻辑(如依赖注入),优先使用拦截器。
  • 如果需要拦截所有请求(包括静态资源),或者需要更底层的控制,优先使用过滤器。

五、全局异常处理

在拦截器或过滤器中,如果验证失败,直接返回错误响应可能会导致客户端无法解析。可以通过全局异常处理机制统一返回 JSON 格式的错误信息。

1. 定义统一响应格式

public class ApiResponse {
    private boolean status;
    private int code;
    private String message;

    // 构造方法和 Getter/Setter 省略
}

2. 全局异常处理器

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(UnauthorizedException.class)
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public ApiResponse handleUnauthorizedException(UnauthorizedException e) {
        return new ApiResponse(false, 401, e.getMessage());
    }
}

3. 在拦截器或过滤器中抛出异常

if (token == null || !isValidToken(token)) {
    throw new UnauthorizedException("Token 无效或未提供");
}

六、总结

通过拦截器或过滤器,可以轻松实现 Spring Boot 项目中所有接口的 Token 验证。以下是两种方式的对比:

特性拦截器(Interceptor)过滤器(Filter)
集成方式Spring MVC 集成Servlet 集成
拦截范围只能拦截 Spring MVC 的请求可以拦截所有请求(包括静态资源)
依赖注入支持不支持
适用场景业务逻辑相关的拦截(如权限验证)底层逻辑相关的拦截(如编码设置)

根据项目需求选择合适的方式,并结合全局异常处理机制,可以构建一个健壮且易维护的 Token 验证系统。希望本文对你有所帮助!


http://www.kler.cn/a/582803.html

相关文章:

  • Rule-Engine 使用介绍
  • upload-labs-master通关攻略(5~8)
  • DeepIn Wps 字体缺失问题
  • 【JavaWeb】快速入门——HTMLCSS
  • 在 Windows 11 下运行 OminiParse V2,详细教程【含问题解决细节】
  • pdf合并工具
  • [多线程]基于单例懒汉模式的线程池的实现
  • Redis 2025/3/9
  • nextJs在DOM视图中渲染未转为状态值的localStorage导致报错
  • mac 被禁用docker ui后,如何使用lima虚拟机启动docker
  • 【实战ES】实战 Elasticsearch:快速上手与深度实践-8.1.2近似最近邻(ANN)算法选型
  • 【Synchronized】不同的使用场景和案例
  • 信号处理之插值、抽取与多项滤波
  • 【C++】C++11新特性
  • ELK traceId 通过A服务调用B服务举例
  • Hive SQL 精进系列:COALESCE 手册
  • 跨境电商IP安全怎么做?从基础到高级防护的实战经验分享
  • 信息学奥赛c++语言:整数去重
  • idea maven 编译报错Java heap space解决方法
  • 华为欧拉操作系统安装Docker服务