news 2026/7/18 5:05:15

Sa-Token全局过滤器解决Spring Boot跨域问题实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Sa-Token全局过滤器解决Spring Boot跨域问题实战

1. 项目概述

在前后端分离架构盛行的当下,跨域问题就像一道无形的墙,让无数开发者头疼不已。最近我在重构公司电商系统时,就遇到了前端Vue项目访问后端Spring Boot接口时的跨域拦截问题。经过多种方案对比,最终选择使用Sa-Token的全局过滤器一站式解决,实测效果非常稳定。

Sa-Token作为轻量级Java权限认证框架,其全局过滤器功能不仅能处理鉴权逻辑,还能优雅地解决跨域问题。相比传统CORS配置方式,它提供了更灵活的三种实现方案:注解式、配置式和代码式,可以适应不同复杂度的项目需求。下面我就结合实战经验,详细拆解这三种方式的实现细节和适用场景。

2. 核心原理剖析

2.1 跨域问题的本质

当浏览器检测到当前请求的协议、域名或端口与当前页面不一致时,就会触发同源策略限制。比如前端部署在https://shop.example.com,而后端API在https://api.example.com,这种跨域访问需要特殊处理。

传统解决方案通常需要在服务端设置以下响应头:

Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET,POST,PUT,DELETE Access-Control-Allow-Headers: Content-Type,Authorization Access-Control-Allow-Credentials: true

2.2 Sa-Token的解决思路

Sa-Token通过全局过滤器(GlobalFilter)在请求进入业务逻辑前统一处理跨域头信息。其核心优势在于:

  1. 非侵入式:不需要修改现有业务代码
  2. 集中管理:统一维护跨域配置
  3. 灵活扩展:支持动态权限控制等复杂场景

过滤器的工作流程如下:

客户端请求 -> SaTokenFilter -> 添加CORS头 -> 业务处理 -> 返回响应

3. 三种实现方案详解

3.1 注解式配置(推荐新手)

在Spring Boot启动类上添加@EnableCors注解是最快捷的方式:

@SpringBootApplication @EnableCors // 启用Sa-Token内置的CORS处理 public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }

这种方式会自动配置以下默认值:

  • 允许所有来源(*)
  • 允许GET/POST/PUT/DELETE方法
  • 允许Content-Type和Authorization头
  • 最大缓存时间3600秒

注意:生产环境建议通过sa-token.cors.allow-origin指定具体域名而非通配符

3.2 配置文件方式

在application.yml中可以进行更精细化的配置:

sa-token: cors: enable: true allow-origin: https://shop.example.com allow-methods: GET,POST,PUT,DELETE,OPTIONS allow-headers: Content-Type,Authorization,X-Requested-With allow-credentials: true max-age: 1800

关键参数说明:

  • allow-credentials:是否允许携带cookie
  • max-age:预检请求缓存时间(秒)
  • 多个域名可用逗号分隔,如allow-origin: https://a.com,https://b.com

3.3 代码编程式配置

对于需要动态判断跨域规则的场景,可以通过实现SaTokenCorsTemplate接口:

@Component public class CustomCorsConfig implements SaTokenCorsTemplate { @Override public CorsConfig getConfig(HttpServletRequest request) { // 动态判断来源 String origin = request.getHeader("Origin"); if(checkOrigin(origin)) { return CorsConfig.create() .setAllowOrigin(origin) .setAllowMethods("GET,POST") .setAllowCredentials(true); } return null; // 不符合条件的来源不处理 } private boolean checkOrigin(String origin) { // 自定义校验逻辑 return origin != null && origin.endsWith(".example.com"); } }

这种方式特别适合:

  • 多环境不同配置(开发/测试/生产)
  • 需要根据请求参数动态控制
  • 白名单域名校验等安全场景

4. 进阶实战技巧

4.1 与权限系统的结合

在全局过滤器中可以同时处理鉴权和跨域:

@Bean public SaTokenFilter saTokenFilter() { return new SaTokenFilter() // 添加拦截规则 .addInclude("/**") .addExclude("/auth/login") // 设置跨域配置 .setBeforeAuth(obj -> { SaHolder.getResponse() .setHeader("Access-Control-Allow-Origin", "*") .setHeader("Access-Control-Allow-Methods", "*") .setHeader("Access-Control-Max-Age", "3600"); }); }

4.2 预检请求优化

对于OPTIONS预检请求,可以提前返回避免进入业务逻辑:

.setBeforeAuth(obj -> { if(SaHolder.getRequest().getMethod().equals("OPTIONS")) { SaHolder.getResponse() .setHeader("Access-Control-Allow-Origin", "*") .setHeader("Access-Control-Allow-Methods", "*") .setHeader("Access-Control-Allow-Headers", "*"); SaRouter.back(); } })

4.3 生产环境配置建议

  1. 禁用通配符*,明确指定允许的域名
  2. 根据业务需要限制HTTP方法
  3. 敏感接口设置allow-credentials: false
  4. 结合Nginx做流量控制和缓存

5. 常见问题排查

5.1 配置不生效检查清单

  1. 确认依赖版本:
<dependency> <groupId>cn.dev33</groupId> <artifactId>sa-token-spring-boot-starter</artifactId> <version>1.45.0</version> </dependency>
  1. 检查过滤器顺序:
# 确保Sa-Token过滤器优先级高于其他过滤器 sa-token.filter-order=high
  1. 查看是否有其他CORS过滤器冲突

5.2 特殊场景处理

案例1:网关层已处理跨域如果项目中使用Spring Cloud Gateway等网关组件,建议:

  • 关闭Sa-Token的CORS配置
  • 统一在网关层处理跨域逻辑

案例2:WebSocket跨域需要在Sa-Token配置外单独处理:

@Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/ws") .setAllowedOrigins("https://shop.example.com") .withSockJS(); }

6. 性能对比测试

使用JMeter对三种方式压测(100并发):

方案类型平均响应时间吞吐量(req/s)CPU占用
注解式23ms452012%
配置文件式25ms438013%
编程式(动态)31ms387015%

测试结论:

  1. 注解式性能最优,适合固定规则
  2. 动态校验带来约30%性能损耗
  3. 实际业务中差异可忽略

7. 安全加固建议

  1. 限制来源域名:
sa-token: cors: allow-origin: https://shop.example.com,https://admin.example.com
  1. 敏感接口禁用CORS:
@SaCheckLogin @PostMapping("/transfer") public Result transfer(@RequestBody TransferDTO dto) { // 金融类接口不开放跨域 SaHolder.getResponse().setHeader("Access-Control-Allow-Origin", ""); }
  1. 定期审计CORS配置:
# 使用OWASP ZAP等工具扫描 zap-cli quick-scan --spider -r https://api.example.com

8. 最终决策建议

根据项目阶段选择方案:

项目阶段推荐方案理由
开发测试注解式快速验证,配置简单
预发布配置文件式环境隔离,便于管理
生产环境编程式+动态校验安全可控,灵活调整

我在电商项目中最终采用混合方案:

  • 管理后台使用编程式动态校验
  • 移动端API使用配置文件式
  • 内部接口完全不开放CORS

这种分层策略既保证了安全性,又满足了不同客户端的访问需求。实际运行半年多来,再未出现跨域相关的生产问题。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/18 5:04:56

C++运算符重载:从基础语法到智能指针实战

1. 项目概述&#xff1a;为什么我们需要运算符重载&#xff1f;在C的世界里&#xff0c;运算符重载&#xff08;Operator Overloading&#xff09;是一个能让你的代码从“能用”跃升到“优雅”和“强大”的关键特性。很多刚接触C的朋友&#xff0c;尤其是从C语言转过来的&#…

作者头像 李华
网站建设 2026/7/18 5:04:14

从零实现游戏内存读写与自动化:基于Cheat Engine与C#的实战指南

1. 项目概述&#xff1a;为什么我们要自己动手读写游戏内存&#xff1f;几年前&#xff0c;我还在为一个简单的游戏自动化需求头疼——想写个脚本自动喝药&#xff0c;或者自动释放某个技能。市面上的“外挂”要么功能不合心意&#xff0c;要么捆绑一堆乱七八糟的东西&#xff…

作者头像 李华
网站建设 2026/7/18 5:04:07

电容串并联原理与应用技巧详解

1. 电容基础概念回顾电容是电子电路中最基础的被动元件之一&#xff0c;它的核心功能是存储电荷。当我们在电路板上看到那些圆柱形或扁平的元件时&#xff0c;其中很多就是不同种类的电容器。理解电容的工作原理对于电路设计和故障排查至关重要。电容的基本单位是法拉(F)&#…

作者头像 李华
网站建设 2026/7/18 5:02:08

ABAP 里的请求路由版图,为什么它不像 Spring MVC 只有一个 HandlerMapping

SAP 官方的 ABAP REST 文档里有一段很有代表性的代码。开发类继承 CL_REST_HTTP_HANDLER,在 IF_REST_APPLICATION~GET_ROOT_HANDLER 方法中创建 CL_REST_ROUTER,再把 /Cars、/Car/{ID} 这样的 URI 模板连接到不同的 ABAP 处理类。请求到达后,框架按照 URI 模板和 HTTP 方法选…

作者头像 李华
网站建设 2026/7/18 5:00:46

Python agent-api 包完全指南:功能、安装、案例与常见错误

1. 引言agent-api 是一个专为 Python 开发者设计的智能体&#xff08;Agent&#xff09;API 封装库&#xff0c;旨在简化与各类 AI Agent 系统的交互。无论是构建自动化工作流、集成大语言模型&#xff08;LLM&#xff09;驱动的智能体&#xff0c;还是管理多 Agent 协作场景&a…

作者头像 李华
网站建设 2026/7/18 4:58:56

地铁车辆编号解析:从记录格式到实用价值全攻略

1. 先搞清楚这个标题到底在说什么如果你看到“【深圳地铁】2号线02A2406株262车&#xff08;赤湾方向&#xff09;出黄贝岭站”这样的标题&#xff0c;第一反应可能是&#xff1a;这是地铁爱好者的专业记录&#xff0c;还是有什么特殊含义&#xff1f;其实这类标题是地铁爱好者…

作者头像 李华