개발을 하면서 꼭 만나게 되는 개념이라고 생각하여 CORS에 대한 글을 정리해보고자 한다.
교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제
웹 애플리케이션은 리소스가 자신의 출처(도메인, 프로토콜, 포트)와 다를 때 교차 출처 HTTP 요청을 실행한다.
보안 상의 이유로, 브라우저는 스크립트에서 시작한 교차 출처 HTTP 요청을 제한한다. 예를 들어, XMLHttpRequest와 Fetch API는 자신의 출처와 동일한 리소스만 불러올 수 있으며, 다른 출처의 리소스를 불러오려면 그 출처에서 올바른 CORS 헤더를 포함한 응답을 반환해야 한다.
CORS 체제는 브라우저와 서버 간의 안전한 교차 출처 요청 및 데이터 전송을 지원한다.
최신 브라우저는 CORS를 사용하여 교차 출처 HTTP 요청의 위험을 완화한다.
만약 우리가 CORS 정책을 위반하는 리소스 요청을 하더라도 서버는 정상적으로 응답을 하고, 이후 브라우저가 이 응답을 분석해서 CORS 정책 위반이라고 판단되면 그 응답을 사용하지 않고 버린다.
즉, CORS는 브라우저의 구현 스펙에 포함되는 정책이기 때문에, 브라우저를 통하지 않고 서버 간 통신을 할 때는 이 정책이 적용되지 않는다.
CORS 정책 위반으로 인한 문제를 해결하는 가장 대표적인 방법은, 서버에서 Access-Control-Allow-Origin 헤더에 알맞은 값을 세팅해주는 것이다.
*
를 사용하여 헤더에 세팅하게 되면 모든 출처에서 오는 요청을 다 받아줘서 당장은 편할 수 있지만, 이상한 출처에서 오는 요청까지 모두 받아서 보안적으로 심각한 이슈가 발생할 수도 있다.출처를 정확히 명시하여 보안적으로 안전하게 하자.
과거에 작업했던 프로젝트의 스프링 코드 일부를 가져왔다. 아래 코드는 http://localhost:3000
에서 들어오는 요청을 모두 허용하게 한다.
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
// 모든 uri에 대해 http://localhost:3000의 접근을 허용한다.
registry.addMapping("/**")
.allowedOrigins("http://localhost:3000")
.allowCredentials(true);
}
}
이와 같이 CORS 정책 위반 시 문제를 겪는 사람은 프론트엔드 개발자이지만, 일반적으로 백엔드 개발자가 문제를 해결해줘야 한다. 이를 해결하는 방법은 그렇게 어렵지 않지만, 처음 이런 문제를 마주치게 된다면 상당히 당황스러울 것이다. 그렇기에 왜 이러한 문제가 발생하고 어떻게 해결할 수 있는지 프론트개발자도 꼭 알아야 하는 개념이라고 생각한다.
reference
https://developer.mozilla.org/ko/docs/Web/HTTP/CORS
https://evan-moon.github.io/2020/05/21/about-cors/