随笔18. @CrossOrigin 注解解决 跨域资源共享(CORS)的问题

1,340 阅读3分钟

在 Spring Boot 项目中,使用 @CrossOrigin 注解可以帮助你解决 跨域资源共享(CORS)的问题。当你在控制器类上直接使用 @CrossOrigin 注解,如下所示:

@CrossOrigin
@RestController
@RequestMapping("/headline")
public class HeadLineController {
    // 控制器的方法
}

这样做的作用

  1. 允许跨域请求

    • @CrossOrigin 注解的主要作用是允许来自不同源(域、协议或端口)的请求访问你的控制器方法。默认情况下,这个注解会允许所有的域发起跨域请求。
  2. 全局应用于控制器

    • @CrossOrigin 放在类级别上,意味着该控制器中的所有请求处理方法都将允许跨域访问。这比在每个方法上单独添加 @CrossOrigin 更为简洁和高效。

@CrossOrigin 的默认行为

当你不指定任何属性时,@CrossOrigin 使用以下默认设置:

  • 允许所有源:任何域都可以发起跨域请求。
  • 允许所有请求方法:如 GETPOSTPUTDELETE 等。
  • 允许所有请求头
  • 不支持凭证:默认情况下,不允许发送凭证(如 Cookies、HTTP 认证信息)。

配置 @CrossOrigin

虽然直接使用 @CrossOrigin 是一种简便的方法,但在实际项目中,可能需要根据具体需求进行配置。例如,限制允许的源、请求方法或请求头。以下是一些常见的配置示例:

  1. 限制特定的源

    @CrossOrigin(origins = "http://example.com")
    @RestController
    @RequestMapping("/headline")
    public class HeadLineController {
        // 控制器的方法
    }
    

    这样配置后,只有来自 http://example.com 的请求被允许跨域访问。

  2. 允许多个源

    @CrossOrigin(origins = {"http://example.com", "http://another-domain.com"})
    @RestController
    @RequestMapping("/headline")
    public class HeadLineController {
        // 控制器的方法
    }
    
  3. 限制请求方法

    @CrossOrigin(origins = "http://example.com", methods = {RequestMethod.GET, RequestMethod.POST})
    @RestController
    @RequestMapping("/headline")
    public class HeadLineController {
        // 控制器的方法
    }
    
  4. 允许凭证

    @CrossOrigin(origins = "http://example.com", allowCredentials = "true")
    @RestController
    @RequestMapping("/headline")
    public class HeadLineController {
        // 控制器的方法
    }
    

安全性考虑

虽然 @CrossOrigin 提供了便捷的跨域访问方式,但直接允许所有源可能会带来安全风险,尤其是在生产环境中。以下是一些安全性建议:

  1. 限制来源

    • 尽量只允许可信的域名进行跨域请求,避免开放给所有域名。通过 origins 属性指定允许的源,可以减少潜在的安全风险。
  2. 限制请求方法和头

    • 只允许必要的请求方法和头,减少恶意请求的可能性。例如,只允许 GETPOST 方法,禁止 DELETE 或其他敏感方法。
  3. 使用凭证

    • 如果需要在跨域请求中发送凭证(如 Cookies),确保 allowCredentials 设置为 true,并且严格限制允许的源。
  4. 全局 CORS 配置

    • 对于大型项目,可能需要更细粒度的 CORS 配置。可以考虑通过全局配置来管理跨域策略,而不是在每个控制器或方法上单独配置。

全局 CORS 配置示例

如果你希望在整个应用中统一管理 CORS 策略,可以在配置类中实现 WebMvcConfigurer 接口,如下所示:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class GlobalCorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**") // 适用于所有路径
                .allowedOrigins("http://example.com", "http://another-domain.com") // 允许的源
                .allowedMethods("GET", "POST", "PUT", "DELETE") // 允许的HTTP方法
                .allowedHeaders("*") // 允许的请求头
                .allowCredentials(true) // 是否允许发送凭证
                .maxAge(3600); // 预检请求的缓存时间(秒)
    }
}

总结

  • 直接在控制器类上使用 @CrossOrigin 是一种简便的方法,适用于简单的跨域需求。
  • 配置具体的跨域策略(如限制源、方法等)可以提高应用的安全性。
  • 全局 CORS 配置 适用于需要在整个应用中统一管理跨域策略的场景,提供更灵活和集中化的管理方式。

根据你的项目需求和安全性考虑,选择合适的方式配置 @CrossOrigin,以确保跨域访问既满足功能需求,又保证应用的安全性。