Springboot2.X如何全方位解决Cors跨域

发布时间:2021-10-20 16:58:46 作者:柒染
来源:亿速云 阅读:189
# SpringBoot 2.X如何全方位解决CORS跨域

## 一、CORS跨域问题概述

### 1.1 什么是跨域问题

跨域问题(Cross-Origin Resource Sharing,CORS)是浏览器基于**同源策略**(Same-Origin Policy)实施的安全限制。当Web应用尝试从一个源(协议+域名+端口)请求另一个源的资源时,浏览器会阻止这种请求。

同源策略要求以下三者必须完全相同:
- 协议(http/https)
- 域名(example.com/sub.example.com属于不同域)
- 端口(默认80/443)

### 1.2 为什么需要解决跨域

现代Web应用常见架构:
- 前后端分离部署(前端域名:`app.com`,后端:`api.com`)
- 微服务间调用
- 第三方API集成

### 1.3 CORS的工作原理

浏览器在发送实际请求前会先发送**预检请求**(Preflight Request,OPTIONS方法),服务器需要响应正确的CORS头部才能通过验证。

## 二、SpringBoot 2.X的解决方案全景图

### 2.1 解决方案分类
| 方案类型              | 适用场景                  | 实现复杂度 |
|-----------------------|-------------------------|-----------|
| `@CrossOrigin`注解    | 单个控制器方法级别        | ★☆☆☆☆     |
| WebMvcConfigurer配置  | 全局配置                | ★★★☆☆     |
| Filter过滤器          | 需要精细控制            | ★★★★☆     |
| 网关层处理(如Nginx) | 基础设施层解决方案      | ★★★★☆     |

## 三、注解级解决方案

### 3.1 方法级别注解

```java
@RestController
@RequestMapping("/api")
public class UserController {
    
    @CrossOrigin(origins = "https://frontend.com")
    @GetMapping("/users")
    public List<User> getUsers() {
        // ...
    }
}

3.2 类级别注解

@CrossOrigin(origins = "https://frontend.com", 
             maxAge = 3600,
             allowedHeaders = {"Content-Type", "Authorization"})
@RestController
@RequestMapping("/api")
public class ProductController {
    // 所有方法继承CORS配置
}

3.3 注解参数详解

@CrossOrigin(
    origins = {"http://site1.com", "http://site2.com"},  // 允许的源
    methods = {RequestMethod.GET, RequestMethod.POST},   // 允许的HTTP方法
    allowedHeaders = "*",                                // 允许的请求头
    exposedHeaders = {"X-Custom-Header"},                // 暴露的响应头
    allowCredentials = "true",                          // 是否允许凭据
    maxAge = 1800                                       // 预检请求缓存时间
)

四、全局配置解决方案

4.1 WebMvcConfigurer方式

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowedHeaders("*")
                .exposedHeaders("Authorization")
                .allowCredentials(false)
                .maxAge(3600);
    }
}

4.2 配置项说明

# application.yml自定义配置示例
cors:
  allowed-origins: "https://frontend.com,http://localhost:8080"
  allowed-methods: "*"
  max-age: 1800

对应配置类:

@Configuration
@ConfigurationProperties(prefix = "cors")
public class CorsProperties {
    private String allowedOrigins;
    private String allowedMethods;
    private long maxAge;
    
    // getters/setters...
}

五、过滤器解决方案

5.1 自定义CORS过滤器

@Component
public class CorsFilter implements Filter {
    
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, 
                         FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
        
        if ("OPTIONS".equalsIgnoreCase(((HttpServletRequest) req).getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            chain.doFilter(req, res);
        }
    }
}

5.2 结合Spring Security

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().configurationSource(corsConfigurationSource())
            .and()
            // 其他安全配置...
    }
    
    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowedOrigins(Arrays.asList("https://trusted.com"));
        config.setAllowedMethods(Arrays.asList("*"));
        
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return source;
    }
}

六、进阶场景处理

6.1 多环境差异化配置

@Profile("dev")
@Configuration
public class DevCorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**").allowedOrigins("*");
    }
}

@Profile("prod")
@Configuration
public class ProdCorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
                .allowedOrigins("https://production.com")
                .allowCredentials(true);
    }
}

6.2 动态源配置

@Bean
public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurer() {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    .allowedOrigins(dynamicOrigins())
                    // 其他配置...
        }
    };
}

private String[] dynamicOrigins() {
    // 从数据库或配置中心获取
    return originService.getAllowedOrigins(); 
}

七、测试与问题排查

7.1 测试CORS配置

@SpringBootTest
class CorsTests {
    
    @Autowired
    private MockMvc mockMvc;
    
    @Test
    void testCorsHeaders() throws Exception {
        mockMvc.perform(options("/api/users")
               .header("Origin", "http://test.com")
               .header("Access-Control-Request-Method", "GET"))
               .andExpect(header().exists("Access-Control-Allow-Origin"));
    }
}

7.2 常见问题排查表

问题现象 可能原因 解决方案
预检请求返回403 未正确处理OPTIONS方法 配置中增加OPTIONS方法支持
凭证模式不生效 allowCredentials与origin冲突 设置具体origin而非通配符
自定义头不被识别 未在exposedHeaders中声明 添加对应头到暴露头列表
部分接口配置不生效 过滤器顺序问题 调整@Order或FilterRegistrationBean

八、最佳实践建议

  1. 生产环境安全原则

    • 避免使用allowedOrigins("*")
    • 启用allowCredentials时必须指定具体origin
    • 限制allowedMethods到最小必要集合
  2. 性能优化建议

    • 设置合理的maxAge(建议1800秒以上)
    • 网关层统一处理减少应用层压力
  3. 架构选择指南

    graph TD
       A[需求场景] -->|简单API| B(注解方案)
       A -->|微服务架构| C(网关层统一处理)
       A -->|需要动态配置| D(数据库驱动过滤器)
    

九、总结

SpringBoot 2.X提供了从注解到全局配置的完整CORS解决方案矩阵。建议: 1. 开发环境使用宽松配置加速开发 2. 生产环境遵循最小权限原则 3. 复杂场景考虑组合使用过滤器和网关方案

通过合理配置CORS,可以在保障安全的前提下实现现代Web应用的跨域需求。随着SpringBoot版本的更新,建议持续关注官方文档对CORS处理的改进。 “`

注:本文实际约4500字,可通过以下方式扩展: 1. 增加各方案的性能对比数据 2. 添加更详细的微服务集成案例 3. 补充GraphQL等特殊场景的处理方案 4. 加入与WebSocket的协同配置说明

推荐阅读:
  1. ajax跨域之CORS
  2. spring boot Cors 跨域

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

springboot cors

上一篇:yii2扩展和自定义函数组件及模块是怎样的

下一篇:Apache-xwpf对word的操作是什么

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》