Что такое CORS и как его настроить в Spring?
CORS (Cross-Origin Resource Sharing) — механизм безопасности браузера, который контролирует, какие домены могут обращаться к ресурсам API. По умолчанию браузеры запрещают JavaScript-коду делать запросы к другому домену (Same-Origin Policy).
Как работает CORS
Простые запросы (GET, HEAD, POST с простыми заголовками) — браузер отправляет запрос напрямую с заголовком Origin:
Пример
GET /api/users HTTP/1.1
Origin: https://frontend.example.com
Ответ:
Access-Control-Allow-Origin: https://frontend.example.com
Предварительные запросы (Preflight) — для «сложных» запросов (PUT, DELETE, кастомные заголовки) браузер сначала отправляет OPTIONS:
Пример
OPTIONS /api/users/42 HTTP/1.1
Origin: https://frontend.example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type, Authorization
Ответ:
Access-Control-Allow-Origin: https://frontend.example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 3600
Настройка в Spring
Три способа настройки CORS
- Аннотация на контроллере:
@RestController
@RequestMapping("/api/users")
@CrossOrigin(origins = "https://frontend.example.com")
public class UserController {
@CrossOrigin(origins = "*", maxAge = 3600)
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) { ... }
}
- Глобальная конфигурация через WebMvcConfigurer:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("https://frontend.example.com")
.allowedMethods("GET", "POST", "PUT", "PATCH", "DELETE")
.allowedHeaders("*")
.allowCredentials(true)
.maxAge(3600);
}
}
- Через Spring Security (если используется):
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.cors(cors -> cors.configurationSource(corsConfigurationSource()))
.csrf(csrf -> csrf.disable())
.build();
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(List.of("https://frontend.example.com"));
config.setAllowedMethods(List.of("GET", "POST", "PUT", "PATCH", "DELETE"));
config.setAllowedHeaders(List.of("*"));
config.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/api/**", config);
return source;
}
Если используется Spring Security, настройку CORS нужно делать через SecurityFilterChain, так как Spring Security обрабатывает запросы раньше WebMvcConfigurer.
На собеседовании: нужно объяснить, зачем нужен CORS (Same-Origin Policy), что такое preflight-запрос и как настроить в Spring. Частая ошибка — ставить
allowedOrigins("*")в продакшне вместо конкретных доменов.