나는 백엔드를 spring 프레임워크로, 프론트를 react 프레임워크로 개발을 할 때 가장 처음 직면한 문제가 있었다. 그것은 바로 'CORS' 문제였다. 아마 대부분의 개발자들이 프론트 담당이든 백엔드 담당이든 개발을 하면서 무조건 적으로 직면하였을 문제이다. 이 글에서는 CORS에 대해 간단하게 설명하고 어떻게 해결하는지를 작성할 것이다. 이를 해결하는 법은 다양하게 있지만 내가 사용하는 방식만을 작성할 것이니 다른 방법이 궁금하다면 다른 글들을 참고해 보길 바란다.
CORS 란 교차 출처 리소스 공유(Cross-Origin Resource Sharing)란 서버가 웹 브라우저에서 리소스를 로드할 때 다른 오리진을 통해 로드하지 못하게 하는 HTTP 헤더 기반 메커니즘이다. 프론트엔드 서버를 만들어서 백엔드 서버와 통신할 때 주로 CORS 에러를 마주친다. 오리진은 프로토콜과 호스트 이름, 포트의 조합을 말한다. 예를들어 http://test.com:3306/test 에서 오리진 즉, 출처는 http://test.com:3306을 뜻한다.
브라우저 환경에서만 적용되는데 일반적으로 브라우저는 스크립트에서 보안을 위해서 교차 출처 HTTP 요청을 제안한다. 리엑트와 스프링을 localhost로서 실행하면 각각 따로 설정을 하지 않는 이상 3000포트와 8080포트를 사용할 것이다. 포트번호가 다르기 때문에 아래와 같은 CORS에러가 나타나는 것이다.
즉, 백엔드에서는 자신의 출처(8080포트)에서가 아닌 다른 오리진(3000포트)을 허용하지 않기 때문에 위와 같은 에러가 발생한 것이다.
이를 해결하는 방법은 크게 두가지 있다. 프론트에서 수정하거나 백엔드에서 수정하거나 할 수 있는데 나는 항상 백엔드 폴더에 파일 하나를 추가해서 해결한다.
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
private static final String DEVELOP_FRONT_ADDRESS = "http://localhost:3000";
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins(DEVELOP_FRONT_ADDRESS)
.allowedMethods("GET", "POST", "PUT", "DELETE")
.exposedHeaders("location")
.allowedHeaders("*")
.allowCredentials(true);
}
}
핵심 부분은 addCorsMapping 부분이다. registry.addMapping()로 백엔드의 어느 주소를 허용할지(위의 코드에서는 "/**"로 설정하여 모든 uri를 허용), allowedOrigins()를 통해서 어느 주소에 권한을 줄지(위의 코드에서는 프론트 서버), allowedMethods()를 통해 어느 http method를, expesedHeaders()를 통해 헤더에 어떤 것을 내보낼지, allowdHeaders()를 통해 어떤 헤더들을 받아들이는 것을 허용할지 등을 확인한다. 그리고 마지막으로 allowCredentials()를 true로 설정하여 CORS 문제를 해결할 수 있는 것이다.
나는 항상 프로젝트를 진행할 때 항상 위의 파일을 먼저 넣고 실시한다. 그리하여 CORS 문제를 해결할 수가 있었다.
프론트에서 수정하는 것은 프록시 서버를 만드는 것이다. 아래는 프록시 서버를 이용 전 사진이다.
CORS 정책에 의해서 막혀진 모습이다.
아래는 프록시 서버를 이용 후 사진이다.
프록시 서버는 프론트엔드 서버에서 요청되는 오리진을 백엔드서버에 맞게(3000포트를 8080포트로) 바꿔줘서 CORS문제를 해결한다.
프록시 서버는 위 문제 해결 외에도 /api요청은 서버1에, /api2요청은 서버2에 요청을 부드럽게 이어줄 수가 있다. 프록시 서버에 관한 내용은 추후 작성해 보겠다.
참고
https://developer.mozilla.org/ko/docs/Web/HTTP/CORS
https://developer.mozilla.org/ko/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials
https://chanto11.tistory.com/67
면접을 위한 CS 전공지식노트 - 주홍철
'CS 기본 지식' 카테고리의 다른 글
개발 - 디자인 패턴 (0) | 2023.05.23 |
---|---|
웹서버와 WAS, 포워드 프록시, 리버스 프록시 (0) | 2023.01.16 |
URL과 URI 의 차이 (0) | 2022.02.22 |
Fanout Service(포스팅 전송 서비스)에서 Push 모델(fanout-on-write)과 Pull(fanout-on-read) 모델 비교 (0) | 2021.11.23 |