문제 상황
팀프로젝트 중 프론트에서 서버 API 요청 시 다음과 같은 에러가 발생했다. "has been blocked by cors policy: no 'access-control-allow-origin' header is present on the requested resource”
브라우저에서 직접 링크 누르면 값이 정상적으로 출력되나 axios로 요청 시 CORS 정책에 의해 접근이 제한된다. CORS가 무엇인지 알아보자.
CORS란 무엇인가?
Cross-Origin Resource Sharing의 약자로, 웹 페이지가 다른 도메인, 프로토콜, 포트를 사용하는 리소스에 접근할 때 발생한다. 기본적으로 브라우저는 같은 출처 정책(Same-Origin Policy)을 따르는데, 이는 보안상의 이유로 한 출처(origin)에서 로드된 문서나 스크립트가 다른 출처의 리소스와 상호 작용하는 것을 제한한다.
즉 origin을 허용해주지 않았거나 origin 자체에 문제가 있을 확률이 높다.
origin은 프로토콜, 호스트, 포트로 이루어져 있다. 프로토콜은 아직 따로 설정하지 않았고. host와 port를 위주로 살펴보려고 한다.
해결 과정
1) 서버측 설정 문제인가?
CORS의 대표적인 해결 방법이다. 서버에서 특정 origin의 접근을 허용하는 방법.
서버가 Access-Control-Allow-Origin 헤더를 포함한 응답을 보내도록 설정하여, 특정 출처에서의 접근을 허용하거나 모든 출처(*)에서의 접근을 허용한다.
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry
.addMapping("/**")
.allowedHeaders("*")
.allowedOrigins("http://localhost:5173")
.allowedMethods("*");
}
}
WebMvcConfigurer를 상속받아 전역적으로 설정하는 방법을 택했다.
프론트 개발환경에서 사용하는 포트도 확인하였고, 혹시 모를 상황에 대비해 origin을 제외한 모든 설정을 허용해 놓은 상태였다.
2) EC2 보안 문제인가?
혹시나 배포중인 EC2 인스턴스에서 접근을 막은 건가 싶어서 AWS에 접속하여 보안그룹 인바운드 규칙을 확인해 보았다.
443, 8080, 80 다 열려있음을 확인
3 도커 문제인가? + log 확인
다음으로는 스프링 서버를 실행중인 도커를 확인해 보았다. 포트 포워딩 문제없고 이미지도 최신으로 pull 되어 있었다. 백그라운드 옵션을 해제하여 로그를 직접 확인해본 결과 쿼리는 정상적으로 실행되고 있었다.
문제가 없는데 왜 안될까 고민을 하다가 충격적인 장면을 목격해버렸다.
문제 해결
@Configuration 어노테이션이 없으니까 전역 설정 안되는게 당연하죠....
아차차... 문제는 나 자신이었던 걸로...