CORS 이슈 이해하고 해결하기!

(이전 블로그에 2019년 9월 23일에 작성된 글을 옮겨 편집한 글입니다)

 

이 포스트에서는 CORS 에러에 대해서 다뤄보려한다.

 

CORS 에러는 웹 개발을 하게 되면 반드시 한 번쯤 겪게되는 이슈로, 클라이언트와 서버의 오리진이 서로 다를 때 발생하는 이슈이다.

 

CORS란 무엇인가?

CORS는 Cross Origin Resource Sharing의 약자로 프로토콜 또는 호스트, 포트가 다른 서버의 자원을 요청하는 매커니즘을 말한다.

 

이때 요청을 할때는 cross-origin HTTP 에 의해 요청된다.

 

하지만 브라우저의 *동일 출처 정책(same-origin policy) 때문에 CORS 같은 상황이 발생하면 외부서버에 요청한 데이터를 브라우저에서 보안목적으로 차단한다. 그로 인해 정상적으로 데이터를 받을 수 없게 된다.

 

브라우저에서 발생한 CORS 에러

 

동일 출처 정책(same-origin policy)
불러온문서나 스크립트가 다른 출처에서 가져온 리소스와 상호작용하는 것을 제한하는 중요한 보안 방식입니다. 이것은 잠재적 악성 문서를 격리하여, 공격 경로를 줄이는데 도움이 됩니다.

- MDN web docs -

 

 

실제로 개발을 하면서 `http://localhost:3000`에서 React를 실행하였고 서버는 `http://localhost:8000`에서 실행하고 있었기 때문에 포트가 달라 CORS가 발생할 수 있는 상황이였다.

const getData = async () => {
    try {
        const response = await axios.get('http://localhost:8000/data');
        return response;
    } catch(err) {
        console.error(err);
    }
}


해결방법

서버와 클라이언트가 같은 프로토콜, 호스트, 포트를 사용하면 에러가 발생하지 않겠지만, 클라이언트와 서버 어플리케이션을 별도의 서버에서 실행하는 지금과 같은 경우에는 서버에서 cross-origin HTTP 요청을 허가 해주는 것이 좋다.

 

CORS에 연관된 대표적인 HTTP 헤더 값은 다음과 같다.

# 헤더에 작성된 출처만 접근할 수 있도록 허용하는 헤더
# * 이면 모든 출처의 접근 허용
Access-Control-Allow-Origin : https://google.com

# 리소스 접근을 허용하는 HTTP 메서드를 지정해 주는 헤더
# * 이면 모든 메소스 허용
Access-Control-Request-Methods : GET, POST, PUT, DELETE, PATCH

# 요청의 자격증명 모드(Request.credentials)가 "include"일 때 요청에 대한 응답을 프로트엔드 자바스트립트 코드에 노출할지 여부를 지정하는 헤더
# 쿠키를 통해 클라이언트의 자격 증명을 해야 하는 경우에 true
Access-Control-Allow-Credentials : true

 


서버 코드에서 CORS 관련 설정 값을 Response 헤더에 추가한다. (예시, express 서버)

app.get('/data', (req, res) => {
    res.header("Access-Control-Allow-Origin", "*"); // 모든 origin 허용
    res.header("Access-Control-Request-Methods", "GET, POST, PUT, DELETE, PATCH"); // 다음 메소드 허용
    res.header("Access-Control-Allow-Credentials", "true"); // cross-origin 간에 인증 주고 받기 허용
    
    res.send(data);
});

 

위 코드에서는 간단하게 모든 오리진 요청에 대한 cross-origin HTTP 요청을 허가하는 헤더를 추가해 주었다.

하지만 위에 처럼 헤더를 모든 오리진 요청에 대해 cross-origin HTTP 요청을 허용해주면 보안적으로 취약해질 수 있기 때문에,  화이트 리스트를 관리하여 리스트에 명시된 오리진만 허용해주는 것이 좋다.

마치며

웹 개발을 하면서 기본이면서도 중요한 이슈인 크로스 도메인 이슈에 대해 정리해 보았는데 정리하면서 정확히 왜 발생하였는지 어떤 맥락에서 생긴 이슈인지 알게 되었던 것 같습니다.

 

또한 단순히 클라이언트와 서버를 개발할때만 발생하는 걸 넘어서 S3와 같은 스토리지 서비스를 사용하는 경우에도 발생할 수 있으니 CORS 에러를 이해하고 있어야 어떻게 해결해야하는지도 알 수 있게 되는 것 같습니다.

 

요약

  • CORS란 프로토콜 또는 호스트, 포트가 다른 서버의 자원을 요청하면 발생하는 이슈이다.
  • 서버와 클라이언트가 분리되어 있는 앱에서는 cross-origin HTTP 요청을 서버에서 승인해주는 것이 좋다.

 

참고자료

 

'Programming > Web' 카테고리의 다른 글

REST API 이해하기!  (0) 2025.02.04