CORS : 운영 서버에서의 문제 해결 경험
사이드 프로젝트를 운영 환경에 배포한 후, 클라이언트 페이지에서 로그인 기능이 정상 작동하는지 확인해보았습니다.
그러나 로그인 실패 메시지와 함께 브라우저 콘솔에는 CORS 오류가 발생했습니다.
Spring Security 설정에 필요한 CORS 허용 설정을 추가했음에도 불구하고 문제가 해결되지 않았습니다.
이 상황을 통해 CORS 에러의 원인을 찾아보고 해결하는 과정에서 배운 점을 정리하고자 합니다.
CORS 오류가 발생한 이유
CORS란?
- CORS(Cross Origin Resource Sharing)는 직역하면 교차 출처 리소스 공유라는 뜻으로 웹 브라우저에서 보안상의 이유로 다른 출처(Origin) 간의 리소스 요청을 제어하는 메커니즘입니다.
기본적으로 웹 페이지가 로드된 출처와 다른 출처의 리소스를 요청할 때 브라우저는 이러한 요청을 차단합니다.
이는 악의적인 사이트가 사용자의 정보에 접근하는 것을 방지 위함입니다. - 출처(Origin) : 프로토콜(Protocol) + 호스트(Host) + 포트(Port) 로 구성되어 있는 정보를 출처라고 합니다.
- ex) https://www.tistory.com:80
- 프로토콜 : https
- 호스트 : www.tistory.com
- 포트 : 80
- ex) https://www.tistory.com:80
- 위 3가지의 정보가 같으면 같은 출처 라고 합니다.
상황
개발 환경에서는 기능 구현에 집중하기 위해 CORS 관련 Origin 설정을 ("*")로 허용하여 모든 출처에서의 요청을 수락하도록 설정했습니다.
운영 환경 배포 시에는 서버 분리 작업과 함께 보안상의 이유로 필요한 출처만 허용하려고 주석만 추가해둔 상태에서 이 버전을
운영 서버에 배포했고, Spring Security의 CORS 설정에서 특정 출처만 허용하는 설정을 추가하지 않아 CORS 오류가 발생했습니다.
이로 인해 클라이언트가 운영 서버의 API에 접근할 수 없어 기능이 정상적으로 작동하지 않았습니다.
이후에 이를 인지하고 CORS 허용 출처를 추가했음에도 불구하고 여전히 동일한 오류가 발생하는 문제가 이어졌습니다.
해결 과정
1. Spring Security 설정에 허용할 출처 추가하기
- 우선 배포 환경에 따른 환경변수를 설정하고 조건문으로 springProfilesActive 환경변수가 PROD 일때와 그렇지 않을 경우에대해 설정을 달리해서 배포를 했다. (아래 Example Code 참고)
- 이렇게 배포했음에도 불구하고 계속해서 CORS 에러가 발생
배포 과정에서 수정한 코드를 배포하지않고 기존 코드를 배포해서30분정도를 허비
// Example Code
public CorsConfigurationSource corsConfigurationSource() {
if (springProfilesActive.equals("PROD")) {
return request -> {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOriginPattern("https://my.com");
config.addAllowedOriginPattern("https://www.my.com");
config.setAllowedMethods(Collections.singletonList("*"));
config.setAllowedOriginPatterns(Collections.singletonList("*"));
config.setAllowCredentials(true);
return config;
};
}
}
2. 브라우저의 개발자도구 확인
- Front 작업은 다른분이 맡아서 하시기에 Code를 직접 확인해보진 않았지만 개발자 도구의 Network 탭을 통해 요청정보를 볼 수 있습니다. URL, Method, Headers 등등
- API 서버에 사용되는 Domain은 다른 Backend 작업자분이 등록을 해주셨는데 Domain을 등록하면 호스팅 사이트에서 서버를 만들면 기본적으로 만들어주는 주소외에 다른 주소를 사용 할 수 있다.
우리 API 서버에 사용되고 있던 주소는 기존 주소를 제외하고 2개였다.- www.api.my.com, api.my.com(redirects to www.api.my.com)
- Network탭을 살펴보면서 Front에서 API 요청에 사용되는 주소는 api.my.com였고 www.api.my.com 으로 Redirect되면서 CORS 에러가 발생하는것이 아닐까 라고 생각했다.
- Front 작업자분에게 API 호출 주소 변경을 요청 후 API 호출이 정상적으로 작동하게 되었습니다.
최종적으로, CORS 오류는 클라이언트가 "api.my.com"로 요청을 보내면 서버가 이를 "www.api.my.com"로 리다이렉트하면서 발생한 것으로 확인되었습니다. 브라우저는 리다이렉트를 다른 출처(origin)로 간주해 CORS 정책에 따라 이를 차단했습니다.
이를 해결하기 위해, 클라이언트 측에서 API 호출 주소를 "www.api.my.com"로 직접 요청하도록 변경하였습니다. 이후 클라이언트와 서버 간의 원활한 통신이 가능해졌고, API 호출이 정상적으로 작동했습니다.
이번 경험을 통해 개발과 운영 환경의 차이를 명확히 구분하는 CORS 설정의 중요성과, 도메인 리다이렉트가 미치는 영향을 배우게 되었습니다. 브라우저의 개발자 도구를 활용해 원인을 탐색하고, 클라이언트-서버 간 통신의 흐름을 면밀히 분석하는 데 큰 도움이 되었습니다.
'개발' 카테고리의 다른 글
| Github Actions으로 서버배포 자동화하기 (1) (1) | 2024.11.17 |
|---|---|
| Github Actions으로 서버배포 자동화하기 (2) (0) | 2024.11.17 |
| Render에 무료로 JAVA + SPRING BOOT 서버 올리기 (1) | 2024.04.25 |