개요
CORS(Cross-Origin Resource Sharing)란, 웹 브라우저에서 실행되는 스크립트가 다른 출처(Origin)의 서버에 접근하는 것을 제한하는 보안 기능입니다. 웹 서버에서 CORS 설정을 하지 않으면, 다른 출처에서 요청이 들어올 때 브라우저에서 차단됩니다.
CORS는 요청하는 출처와 응답하는 출처가 다를 때, 브라우저가 보안상의 이유로 데이터를 차단하는 기능입니다. 이러한 보안상의 이유는 다른 출처에서의 요청이 중요한 데이터를 탈취하거나 악성코드를 심어 보안에 침해할 수 있기 때문입니다.
해결방법
@CrossOrigin 어노테이션
@CrossOrigin 어노테이션은 특정 컨트롤러나 메서드에 대해 CORS를 허용하도록 설정합니다.
@RestController
public class MyController {
@CrossOrigin(origins = "http://localhost:8080")
@GetMapping("/hello")
public String hello() {
return "Hello World!";
}
}
위 코드는 http://localhost:8080 도메인에서 온 요청만 허용합니다.
WebMvcConfigurer
WebMvcConfigurer 인터페이스를 구현하여 Spring MVC의 기본 동작을 변경할 수 있습니다.
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:8080")
.allowedMethods("GET", "POST")
.allowCredentials(false)
.maxAge(3600);
}
}
위 코드는 모든 경로에서 http://localhost:8080 도메인에서 온 GET과 POST 요청만 허용합니다. 또한, 인증 정보를 허용하지 않으며, 최대 3600초 동안 캐시합니다.
Global CORS Configuration
글로벌 설정은 스프링 부트의 경우 application.properties 파일에 다음과 같이 설정할 수 있습니다.
spring.mvc.cors.allowed-origins=http://localhost:8080
spring.mvc.cors.allowed-methods=GET, POST
spring.mvc.cors.allow-credentials=false
spring.mvc.cors.max-age=3600
위 설정은 위의 WebMvcConfigurer와 동일한 설정을 적용합니다.
필터
CORS 요청을 처리하는 필터를 작성하여 사용할 수도 있습니다.
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, X-Requested-With, remember-me");
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
}
}
}
위 코드는 모든 도메인에서 모든 메서드를 허용합니다. 또한, 인증 정보와 함께 Authorization, Content-Type, X-Requested-With, remember-me 헤더를 허용합니다. OPTIONS 메서드를 허용하며, 응답 코드를 200으로 설정합니다.
CorsConfigurationSource 인터페이스 사용
이 방법은 WebMvcConfigurer를 구현하거나 @Configuration 어노테이션을 붙인 클래스를 만들어서 처리할 수 있습니다.
@Bean
public CorsConfigurationSource corsConfigurationSource(){
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*"); // 모든 origin 허용
corsConfiguration.addAllowedMethod("*"); // 모든 HTTP method 허용
corsConfiguration.addAllowedHeader("*"); // 모든 header 허용
corsConfiguration.setAllowCredentials(true); // credential 허용
// allowCredentials 를 true로 하였을 때,
// allowedOrigin의 값이 * (즉, 모두 허용)이 설정될 수 없도록 검증합니다.
config.validateAllowCredentials();
// 어떤 경로에 이 설정을 적용할 지 명시합니다. (여기서는 전체 경로)
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return source;
}
'스프링' 카테고리의 다른 글
[스프링 시큐리티] 시큐리티 동작 과정, UserDetails, UserDetailsService. (0) | 2023.02.17 |
---|---|
[스프링][자바]Reflection API (0) | 2023.02.15 |
[스프링] DI, IoC, Bean (0) | 2023.02.13 |
[스프링] 즉시로딩과 지연로딩 (0) | 2023.02.10 |
[스프링] 프록시란 (0) | 2023.02.10 |