본문 바로가기
백엔드

[SERVER] CORS preflight request 에러

by 더하리 2024. 7. 21.

 

문제상황

~ has been blocked by CORS policy: Response to preflight request doesn't pass access control check

→ 프론트와의 통신에서 계속해서 위와 같은 오류 메세지가 떴다.

 

//1) WebMvcConfig 파일
// Access-Control-Allow-Origin 헤더 설정
(중략)
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOriginPatterns("*")
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                .allowedHeaders("*")
                .allowCredentials(true); // 인증 정보를 포함한 요청을 허용할 경우 필요

    }
//2) 인터셉터 prehandler에 추가해준 코드
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
    return true;
}

보통 CORS 에러가 날때는 백엔드에서 다음과 같은 설정을 해주면 해결이 된다고 하는데...(보통은 위 1, 2 설정해주면 됨!)

 

해결이 되지 않는 상황에 봉착하였고.. 

아래와 같은 403 (invalid CORS request) 에러가 계속해서 났다

 

해결

결론적으로는

프론트에서 proxy설정을 하지 않아야하는 상황에서 설정을 하면서 백엔드에서 CORS관련 설정을 해줘도 잘 먹히지 않았던 것이다. 혹시나 해줄수있는 설정을 다해줘도 해결이 되지 않는다면 프론트측 설정을 다시 확인하고 불필요한 설정을 추가로 하면서 로직이 꼬이진 않았는지 확인하기!!

 

이번에 처음 알게 됐던 것은 다른 서버에서 요청을 주고받게 되면 설정한 메소드(GET, POST 등)의 요청이 바로 오는 것이 아니라 OPTIONS 요청이 먼저 온다는 것❗

실제 요청 전에 오는 OPTONS

 

이번 기회를 통해 CORS에 대해 찾아보게 되어 공유해보려 한다.


 

CORS(Cross-Origin Resource Sharing)란? 

"교차 출처 리소스 공유" 뜻처럼, 다른 Origin 간에 리소스를 공유할 수 있도록 허용해주는 정책을 의미한다.

Origin은 URL에서 도메인만 의미하는 것이 아닌 프로토콜포트까지 포함하는 개념으로 그림으로 확인해보자.

출처: https://docs.tosspayments.com/resources/glossary/cors

 

즉, 이 세가지 요소중 하나라도 다르다면 CORS에러를 만나게 되는데 이렇게 서로 다른 출처가 교차한다는 것을 허용해주는 것이 CORS를 설정한다는 것이다. ( "출처가 다른 서버 간의 리소스 공유"를 허용한다.)

 

과거에는 프론트와 백이 크게 분리되어 있지 않아 같은 Origin에 있어 문제가 발생하지 않았지만 분리되기 시작하면서 문제가 발생했고 백엔드 서버는 어떤 Origin에서 요청이 왔을때 받을 것인지 정의해줄 필요가 생겨서 등장하게 되었다고 한다.

SOP

더불어 CORS와 같이 비교되는 개념 중 하나가 SOP인데 SOP는 Same-Origini Policy 웹 보안 정책으로 동일 출처가 아닌 리소스 요청을 차단하는 것으로 보안을 강화하는 메커니즘이다. 반대로 CORS는 SOP 제한을 완화하여 다른 출처 간의 안전한 데이터 교환을 가능하게 한다는 차이가 있다. 

 

 

그렇다면 위에서 언급한 Preflight error의 원인은 무엇일까?

다른 origin 간에 요청을 전송하기 전에 OPTIONS 메소드로 Preflight(단어 뜻: 비행 전에 일어나는) 요청을 보내는데 이때 OPTIONS 요청을 처리해주는 곳이 없기 때문에 error가 발생하는 것이다.

 

preflight request 는 브라우저가 서버에 실제 요청을 보내기 전에 허가를 받기 위해 보내는 요청으로 서버는 실제 요청이 허용되는지(허용 origin, 메소드, 헤더 등) 여부를 응답한다. 이때 이 preflight request 는 OPTIONS 메서드에 의해 만들어지기 때문에 서버에서 OPTIONS 메서드를 허용해주는 것!

 

 

CORS에는 다양한 유형의 요청이 있는데 그 중 하나가 preflight reqest이고 이 외에도

simple request  ( 브라우저가 추가적인 검증 없이 바로 서버에 전송할 수 있는 요청 -만족해야하는 조건 존재 )

credentialed request  ( 쿠키, 인증 헤더 등의 자격 증명(credentials)이 포함된 요청 )

 

위와 같은 유형의 요청도 있다고 하니 참고하면 좋을 것 같다.

 

 

HOW TO SOLVE?

way 1) 서버에서 Access-Control-Allow-Origin 응답 헤더 세팅하기

초입에서 적은 코드와 같이 Access-Control-Allow-Origin응답 헤더를 설정하여 요청을 수락할 출처, 메소드, 헤더 등을 명시적으로 지정해준다.

 

way 2) 프록시 서버 사용하기

프록시 서버를 사용하여 CORS 문제를 우회하는 방법으로, 웹 애플리케이션이 리소스를 직접적으로 요청하는 것이 아닌, 프록시 서버를 사용해 웹 애플리케이션에서 리소스로의 요청을 전달하는 방법이다.

즉, 프록시 서버 설정으로 클라이언트의 요청을 실제 API 서버로 전달하고, 응답을 다시 클라이언트로 전달하는 방식이기에 해당 방법을 사용하면 리소스와 동일한 출처에서 요청을 보내는 것처럼 보여 CORS에러를 방지할 수 있다. 

 

 

 


 

평소에는 당연하다고만 생각했던 부분들을

다시한번 생각해보고 공부해볼 수 있어서 흥미로웠던 것 같다!!

조금은 더 인터넷 구조를 깊이 이해하게 된 것 같고

더 공부해봐야겠다!

 

오늘도 모두 수고하셨습니다:)

 

 

 

 

*참고자료*

 

CORS(교차 출처 리소스 공유) | 토스페이먼츠 개발자센터

CORS를 번역하면 “교차 출처 리소스 공유”에요. ‘두 출처가 서로 다르다’는 뜻인데요. CORS를 설정한다는 건 ‘출처가 다른 서버 간의 리소스 공유’를 허용한다는 거죠.

docs.tosspayments.com

 

CORS와 관련 있는 preflight request란?

CORS(Cross-Origin Resource Sharing)에 대해서 자료를 살펴보던 중에 preflight request라는 용어를 접하게 되어 내용을 정리해봤습니다. CORS란? 우선 CORS에 대해서 설명이 필요하겠죠? CORS, Cross-Origin Resource shar

bskyvision.com

 

 

[Server] CORS Preflight 에러

WebSecurityConfig의 CORS 에 필요한 내용과 Origin 을 설정해 주었는데도 아래와 같은 오류 발생(프론트 쪽에서 나타난 CORS 오류)Preflight error : cross origin 요청을 전송하기 전에 OPTIONS 메소드로 Prefligh

velog.io