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

06-01 1015阅读

文章目录

      • 学习文章: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() {
                        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
                        registrationBean.setFilter(new TokenFilter());
                        registrationBean.addUrlPatterns("/*"); // 拦截所有路径
                        registrationBean.setOrder(1); // 设置过滤器顺序
                        return registrationBean;
                    }
                }
                

                3. 测试过滤器

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


                四、拦截器 vs 过滤器

                1. 拦截器的优势

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

                  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 验证系统。希望本文对你有所帮助!

                      Spring Boot 中实现全局 Token 验证的两种方式
                      (图片来源网络,侵删)
                      Spring Boot 中实现全局 Token 验证的两种方式
                      (图片来源网络,侵删)
                      Spring Boot 中实现全局 Token 验证的两种方式
                      (图片来源网络,侵删)
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

目录[+]

取消
微信二维码
微信二维码
支付宝二维码