프론트와 연동하는 과정에서 다음과 같은 오류가 발생했다.
에러 메세지를 보면 CORS 정책에 의해 HTTP 요청이 block 처리 되었다는 것을 알 수 있었다.
일단 CORS 정책이 뭔지 왜 필요한지 짚고 넘어갈 필요가 있다.
웹 브라우저에서 통신을 할 때, 보안을 위해 출처(Origin)에 따라 리소스를 공유하는 행위를 막는 정책은 크게 두가지 정책이 있다.
하나는 위에서 나온 CORS(Cross Origin Resourse Sharing : 교차 출처 자원 공유) 정책이고, 또 하나는 SOP(Same Origin Policy : 동일 출처 정책)이다. 직역으로 인해 “교차 출처”라는 말이 잘 와닿지 않을 수 있는데 참고한 포스팅에서 “다른 출처”라는 표현을 추천해줬는데 해석하기 더 용이한 것 같다.
그러면 출처가 서로 같고 다른 것은 어떤 기준으로 판단할까?
출처를 의 동일함을 판단하는 기준은 두 URL의 구성 요소 중에서 Scheme
, Host
, Port
이다.
예를 들어, API 개발자가 설정하는 요소인 경로(path), query parameter가 다른 값이라도 위 3가지 요소가 같으면 같은 출처로 판단한다.
CORS에 대한 사전 지식은 위에 작성한 것으로 충분한 것 같다.
우리 프로젝트(에브리벤트)에서는 CorsFilter를 bean으로 등록하고, WebSecurityConfig에서 filter를 추가하는 방식으로 CORS 정책에 대한 설정을 하고 있다. 아래의 코드를 보면 허용 출처(AllowedOrigin)를 설정하는 코드를 작성했는데 프론트 로컬 테스트 출처인 “http://localhost:3000”와 prod 출처인 “https://everevent-be69d.web.app:443” 만 허용 출처로 추가를 한 상태였다.
@Configuration
public class CorsConfig {
@Bean
publicCorsFilter corsFilter(){
UrlBasedCorsConfigurationSource source =newUrlBasedCorsConfigurationSource();
CorsConfiguration config =newCorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("http://localhost:3000");
config.addAllowedOrigin("https://everevent-be69d.web.app:443");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
config.addExposedHeader("X-AUTH-TOKEN");
source.registerCorsConfiguration("/api/v1/**", config);
return newCorsFilter(source);
}
}
Json이 보내준 포스팅에 따르면 동일 출처를 판단하는 기준 중 포트 번호를 명시한 출처는 브라우저의 구현 로직에 따라 동일 출처로 판단하지 않을 수 있다.
예를 들어 “https://www.example.com”에서 서버에 요청을 날렸을 때, 서버 측 CORS 설정이 “https://www.example.com:443”일 경우 둘 간의 출처에 대한 판단이 브라우저마다 상이하다는 것이다.
위 내용을 참고하여, 아래와 같이 포트번호를 생략한 URL을 CORS 설정의 허용 출처에 추가하였다.
config.setAllowCredentials(true);
config.addAllowedOrigin("http://localhost:3000");
config.addAllowedOrigin("https://everevent-be69d.web.app");
config.addAllowedOrigin("https://everevent-be69d.web.app:443");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
config.addExposedHeader("X-AUTH-TOKEN");
source.registerCorsConfiguration("/api/v1/**", config);