본문 바로가기
CS 기본 지식

백엔드, 프론트 서버를 연결할 때: 'CORS' 문제 및 해결법

by khds 2023. 3. 20.

 

나는 백엔드를 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에러가 나타나는 것이다. 

 

프로젝트 진행중 마주친 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

 

교차 출처 리소스 공유 (CORS) - HTTP | MDN

교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라

developer.mozilla.org

 

https://developer.mozilla.org/ko/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials

 

Access-Control-Allow-Credentials - HTTP | MDN

응답헤더 Access-Control-Allow-Credentials 는  요청의 자격증명 모드(Request.credentials)가 "include" 일때,   브라우저들이 응답을 프로트엔드 자바스트립트 코드에 노출할지에 대해 알려줍니다.

developer.mozilla.org

 

https://chanto11.tistory.com/67

 

[웹 보안] CSRF, CORS, XSS, CSP

CSRF Cross-Site Request Forgery : 사이트 간 요청 위조 CSRF 는 공격자가 사용자가 현재 로그인된 사이트에 대해 강제로 작업을 실행하게하는 공격 입니다. // 공격 시나리오 1. 'example.com'을 방문합니다. 2.

chanto11.tistory.com

 

https://itstory.tk/entry/CSRF-%EA%B3%B5%EA%B2%A9%EC%9D%B4%EB%9E%80-%EA%B7%B8%EB%A6%AC%EA%B3%A0-CSRF-%EB%B0%A9%EC%96%B4-%EB%B0%A9%EB%B2%95

 

CSRF 공격이란? 그리고 CSRF 방어 방법

CSRF 공격(Cross Site Request Forgery)은 웹 어플리케이션 취약점 중 하나로 인터넷 사용자(희생자)가 자신의 의지와는 무관하게 공격자가 의도한 행위(수정, 삭제, 등록 등)를 특정 웹사이트에 요청하게

itstory.tk

 

면접을 위한 CS 전공지식노트 - 주홍철