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

别再乱写Filter和Interceptor了!SpringBoot登录校验实战,从令牌生成到统一拦截的完整流程

别再乱写Filter和Interceptor了SpringBoot登录校验实战精要登录校验是每个JavaWeb开发者必须掌握的核心技能但很多人在实际项目中常常陷入技术选型的困惑——Filter和Interceptor究竟该如何选择如何避免常见的配置陷阱本文将带你从零构建一套完整的JWT登录校验体系涵盖令牌生成、统一拦截、异常处理全流程并深度解析Filter与Interceptor的适用场景与最佳实践。1. 技术选型Filter vs Interceptor的本质差异1.1 架构层级与执行顺序Filter和Interceptor最根本的区别在于它们的架构层级// Filter属于Servlet规范 public class AuthFilter implements Filter { Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 预处理逻辑 chain.doFilter(request, response); // 放行 // 后处理逻辑 } } // Interceptor属于Spring MVC框架 public class AuthInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { // 控制器方法执行前处理 return true; // 是否继续执行 } }它们的执行顺序遵循以下管道以典型请求为例Filter层CharacterEncodingFilter→CorsFilter→自定义AuthFilterDispatcherServlet路由匹配Interceptor层LogInterceptor→AuthInterceptorController方法业务逻辑处理关键提示Filter对所有请求生效包括静态资源而Interceptor只拦截Controller方法调用1.2 核心能力对比通过下表可以清晰看出两者的适用场景特性FilterInterceptor依赖框架Servlet规范JavaWeb标准Spring MVC框架作用范围所有HTTP请求仅Controller方法调用获取上下文Servlet API原生对象HandlerMethod参数解析异常处理需自行实现可结合ExceptionHandler性能开销较低略高需经过Spring上下文典型应用场景跨域处理、字符编码、全局认证权限校验、日志记录、参数预处理1.3 经典误用场景分析案例1路径匹配陷阱// 错误配置Interceptor使用Servlet路径模式 registry.addInterceptor(authInterceptor) .addPathPatterns(/api/*); // 无法匹配/api/users/1 // 正确做法使用Ant风格路径 registry.addInterceptor(authInterceptor) .addPathPatterns(/api/**);案例2注解扫描遗漏// 忘记添加扫描注解导致Filter失效 SpringBootApplication ServletComponentScan // 必须添加 public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }2. JWT令牌生成与校验实战2.1 令牌生成最佳实践采用JJWT库实现安全的令牌签发public class JwtUtils { private static final String SECRET_KEY your-256-bit-secret; private static final long EXPIRATION 86400000; // 24小时 public static String generateToken(UserDetails user) { return Jwts.builder() .setSubject(user.getUsername()) .claim(roles, user.getAuthorities()) .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() EXPIRATION)) .signWith(SignatureAlgorithm.HS256, SECRET_KEY) .compact(); } }安全要点使用HS256算法配合足够长度的密钥设置合理的过期时间建议≤24小时不要在令牌中存储敏感信息如密码2.2 统一校验架构设计推荐采用FilterInterceptor双校验的混合模式Filter层基础校验令牌存在性、格式验证Interceptor层细粒度权限控制角色校验、权限匹配// Filter基础校验示例 public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request (HttpServletRequest) req; String token request.getHeader(Authorization); if (token null || !token.startsWith(Bearer )) { sendError(response, 401, Missing token); return; } try { Claims claims JwtUtils.parseToken(token.substring(7)); request.setAttribute(userClaims, claims); chain.doFilter(request, response); } catch (JwtException e) { sendError(response, 403, Invalid token); } }3. 异常处理与响应封装3.1 全局异常处理机制建立统一的错误响应体系RestControllerAdvice public class GlobalExceptionHandler { ExceptionHandler(AuthenticationException.class) public ResponseEntityErrorResponse handleAuthError(AuthenticationException ex) { return ResponseEntity.status(401) .body(new ErrorResponse(401, AUTH_ERROR, ex.getMessage())); } ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntityErrorResponse handleValidationError( MethodArgumentNotValidException ex) { String message ex.getBindingResult().getAllErrors() .stream().map(DefaultMessageSourceResolvable::getDefaultMessage) .collect(Collectors.joining(; )); return ResponseEntity.status(400) .body(new ErrorResponse(400, VALIDATION_ERROR, message)); } }3.2 响应体标准化定义通用响应结构public class ApiResponseT { private int code; private String message; private T data; private long timestamp System.currentTimeMillis(); // 成功响应快捷方法 public static T ApiResponseT success(T data) { ApiResponseT response new ApiResponse(); response.code 200; response.message success; response.data data; return response; } }4. 性能优化与安全加固4.1 缓存令牌校验结果避免重复解析JWT带来的性能开销Cacheable(value tokenCache, key #token) public Claims validateAndCacheToken(String token) { return Jwts.parser() .setSigningKey(SECRET_KEY) .parseClaimsJws(token) .getBody(); }4.2 安全防护措施CSRF防护对关键操作添加随机Token校验防重放攻击在JWT中加入jtiJWT ID和nonce速率限制对登录接口实施限流如Guava RateLimiter// 限流器配置示例 Bean public RateLimiter loginRateLimiter() { return RateLimiter.create(5); // 每秒5个请求 } PostMapping(/login) public ApiResponseString login(RequestBody LoginRequest request) { if (!loginRateLimiter.tryAcquire()) { throw new RateLimitException(Too many requests); } // ...正常登录逻辑 }5. 现代替代方案Spring Security整合对于复杂系统建议采用Spring Security JWT组合方案EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .antMatchers(/auth/**).permitAll() .anyRequest().authenticated() .and() .addFilter(new JwtAuthenticationFilter(authenticationManager())) .addFilter(new JwtAuthorizationFilter(authenticationManager())) .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS); } }迁移路径建议从简单Filter/Interceptor开始原型开发随着业务复杂度的提升逐步引入Spring Security关键路径保持双重校验机制登录校验系统的设计需要根据实际业务场景灵活调整。在最近的一个教育管理系统项目中我们采用Filter处理基础认证Interceptor实现权限控制的混合模式配合Redis缓存令牌信息使系统在日均10万次请求下保持50ms的认证延迟。记住没有放之四海而皆准的方案只有最适合当前业务阶段的技术选型。
http://www.gsyq.cn/news/1333710.html

相关文章:

  • Kafka 与 RocketMQ 在事务消息实现机制上有什么区别?
  • 智能散热革命:如何用FanControl精准掌控你的电脑风扇噪音与温度平衡
  • 抖音批量下载终极指南:3分钟学会免费无水印下载
  • 国家电网PPT:山东省域台区云储能关键技术及工程应用
  • FFmpeg硬件加速全解析:从原理到实战的跨平台优化指南
  • 2026企业招聘平台选择趋势:前程无忧成为多类型岗位招聘的重要平台
  • 一文搞懂MCP、Skill、Agent
  • 【求助】鸿蒙ArkTS TextArea 编辑器核心问题求助
  • HarmonyOS 6 ArkGraphics 3D精讲:从旋转立方体看鸿蒙原生3D能力
  • 为OpenWrt开源路由器添加WiFi 7支持:USB网卡驱动编译与配置实战
  • 5分钟快速上手:Parsec VDD虚拟显示器完整指南,彻底释放游戏串流潜能
  • 工业网络零中断的秘密:手把手教你理解并配置PRP协议(基于IEC 62439-3)
  • 湿敏电阻HR202/CM-R的两种驱动方案详解:IO充放电法 vs. 交流方波AD采样
  • 真空断路器用新型永磁操动机构设计优化与控制技术【附代码】
  • Office自动化安装:告别繁琐配置,享受一键部署体验
  • 水泵电机热保护器:原理、选型、安装与故障排查全解析
  • 3分钟学会免费下载网易云QQ音乐歌词:本地音乐完美解决方案
  • 从零编译AOSP 10.0并刷入Pixel 3:完整环境搭建与实战指南
  • 2026年毕业季|十款免费降AI工具测评,哪款最好用? - 降AI实验室
  • 别再花钱买云数据库了!手把手教你用Docker在NAS上免费搭建MySQL(以绿联DX4600为例)
  • 3步搞定MASA模组全家桶汉化:小白也能懂的完整教程
  • Collection | Gut–X axis
  • 手把手教你用Obsidian+Excalidraw画流程图,告别切换软件的麻烦
  • 别再只会用SU01了!手把手教你用PFCG搞定SAP权限配置,从MM01物料创建权限说起
  • Arduino步进电机控制:按键调速与定时器中断实现
  • ISCE2安装实录:从踩遍GitHub issue里的坑,到总结出这份WSL2+Miniconda的保姆级避坑指南
  • 【2026】ISCC 数字古墓
  • ARM多核原子同步实战:从LDADD指令到RTOS锁调试
  • Verilog/SystemVerilog初始化陷阱:仿真与硬件差异解析
  • 别再手动整理文献了!用Python+Semantic Scholar API,5分钟搞定论文参考文献列表