CORS

안준성·2024년 5월 23일

Project::BoardPick

목록 보기
11/11

보드픽 프로젝트를 진행하면서

프론트에서 백엔드로 API 요청을 할 때,

CORS policy 문제가 발생했다.

이와 관련된 내용들에 대해 알아보자.


SOP

기본적으로 웹 브라우저는 보안상의 이유로

동일한 출처(origin)에 대해서만 리소스를 공유할 수 있도록 제한하는데,

이것을 SOP(Same-Origin Policy)라고 한다.

여기서 origin이란 protocol, host, port 번호의 조합을 의미한다.

예를 들어, https://naver.com에서는
httpsprotocol,
naver.comhost이며
port 번호는 여기선 생략되어 있지만 https의 기본 포트인 443이 포트번호가 된다.

이 3개가 모두 같아야 같은 오리진이고 하나라도 다르면 다른 오리진으로 간주된다.

이 정책 덕분에 악의적인 웹 사이트가 사용자의 데이터를 훔치는 것을 방지할 수 있지만,

나 같은 선량한 웹 개발자에겐 불편함만 줄 뿐이다.

CORS

이러한 제한을 완화하기 위해 도입된 것이 바로 CORS(Cross-Origin Resource Sharing)이다.

CORS는 특정 오리진의 리소스를 허용할 수 있도록
서버 측에서 HTTP 헤더를 설정하는 방식으로 동작한다.
이를 통해 클라이언트는 명시된 오리진으로부터 리소스를 요청할 수 있게 된다.

설정 방법

그럼 Spring으로 API 서버를 구현할 때,

CORS를 설정하는 방법에 대해 알아보자.

CORS를 설정하려면 응답 헤더에 다음과 같은 정보를 포함시켜야 한다.

Access-Control-Allow-Origin // 허용할 origin을 명시
Access-Control-Allow-Methods // 허용할 HTTP 메서드를 명시
Access-Control-Allow-Headers // 허용할 HTTP 헤더를 명시

이걸 전부 다 해야 하는건 아니고 내가 원하는 것만 하면 된다.

물론 설정하지 않으면 SOP에 따라 기본적으로 허용되지 않는다.

나는 이렇게 했다.

    protected CorsConfigurationSource corsConfigurationSource() {

        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin(Uri.MAIN_PAGE.getDescription());
        corsConfiguration.addAllowedOrigin("http://localhost:3000");
        corsConfiguration.addAllowedOrigin("http://localhost:8080");
//        corsConfiguration.addAllowedOrigin("https://accounts.kakao.com");
        corsConfiguration.setAllowCredentials(true);
        corsConfiguration.addAllowedMethod("*");
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addExposedHeader("Authorization");
        corsConfiguration.addExposedHeader("Content-Type");
        corsConfiguration.addAllowedHeader("Authorization");
        corsConfiguration.addAllowedHeader("Content-Type");

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", corsConfiguration);

        return source;
    }

프론트 서버의 메인 페이지를 허용해줬고
개발 용으로 localhost:3000과 8080을 허용해줬다.

HTTP와 HTTPS

여기서 나는 cors 설정까지 해줬는데도 문제가 해결되지 않았는데,
프론트 서버는 HTTPS를 사용하고 백엔드 서버는 HTTP를 사용하여
다른 오리진으로 인식됐기 때문이었다.

해당 문제도 마찬가지로 HTTPS URL 요청에 대해 열어주는 식으로 해결이 가능한거 같긴 한데(안해봐서 모름),
나는 그냥 백엔드 서버도 HTTPS를 사용하게 바꿔주었다.

나는 백엔드 서버를 EC2에서 호스팅하고 있었기 때문에,
해당 포스팅를 보고 따라 설정해주었다.

Proxy를 이용한 CORS 해결

CORS 문제를 해결하기 위한 또 하나의 방법으로 Proxy를 사용하는 것이 있다.

Proxy 서버는 클라이언트와 서버 사이에서

각각에 대해 같은 오리진인척 하여 SOP 정책을 우회할 수 있다.

물론 말 그대로 우회법이라 개발환경에서만 사용해야 하고,

배포 환경에서는 보안과 성능 측면에서 권장되지 않는다.

결론

CORS는 웹 보안 정책인 SOP의 제한을 완화하기 위해 도입된 표준으로

서버는 특정 origin의 리소스를 허용할 수 있도록

응답 헤더에 CORS 관련 정보를 포함시켜야 하며,

이를 통해 클라이언트는 명시된 origin으로부터 리소스를 요청할 수 있게 된다.

profile
안녕하세요

0개의 댓글