- 정의와 목적:
- CORS는 웹 페이지의 스크립트가 페이지를 제공한 도메인과 다른 도메인에 요청을 할 수 있도록 하는 프로토콜입니다. 이는 여러 서버나 도메인에서 자원을 필요로 하는 웹 애플리케이션에 종종 필요합니다.
- 기본적으로 웹 브라우저는 보안상의 이유로 이러한 교차 출처 요청을 차단합니다.
- 출처 개념:
- 출처는 스킴(프로토콜), 도메인(호스트), 포트의 조합으로 구성됩니다.
- 다른 출처:
- 다른 스킴 (예: HTTP vs. HTTPS)
- 다른 도메인
- 다른 포트
- 브라우저의 기본 동작:
- Chrome, Firefox, Safari와 같은 최신 브라우저는 보안상의 이유로 기본적으로 교차 출처 요청을 차단합니다.
- 이는 공격이나 취약점이 아니라 웹 애플리케이션을 악의적인 활동으로부터 보호하기 위한 보안 기능입니다.
- 교차 출처 통신:
- 한 도메인에서 실행 중인 UI 애플리케이션이 다른 도메인에 있는 백엔드 API와 통신하려고 할 때, 브라우저는 CORS로 인해 이 통신을 차단합니다.
- 예시:
- https://domain1.com에서 실행 중인 UI 애플리케이션
- https://domain2.com에서 실행 중인 백엔드 API
- 보안적 의미:
- CORS는 권한 없는 교차 출처 요청을 방지함으로써 보안 위협을 완화합니다.
- 이는 해커가 다른 출처를 악용하여 데이터를 훔치거나 악의적인 행동을 하는 것을 방지합니다.
- 교차 출처 요청 허용:
- 프론트엔드 애플리케이션이 다른 도메인에 호스팅된 백엔드 서버와 상호 작용해야 하는 경우와 같이, 교차 출처 통신이 필요한 합법적인 시나리오가 있습니다.
- 이러한 경우, 서버 측에서 올바른 구성을 통해 안전하게 교차 출처 요청을 허용해야 합니다. 이는 일반적으로 허용된 출처, 메서드 및 헤더를 지정하는 방식으로 설정됩니다.
- CORS 구성:
- 서버 측에서 CORS를 구성하여 어떤 출처가 자원에 접근할 수 있는지 지정할 수 있습니다.
- 이는 Access-Control-Allow-Origin과 같은 HTTP 헤더를 설정하여 특정 도메인을 허용하는 방식으로 이루어집니다.
- CORS 설정 방법:
- Spring Security 프레임워크를 사용하여 두 가지 방법으로 CORS를 설정할 수 있습니다.
- 첫 번째 방법: @CrossOrigin 주석 사용:
- REST 컨트롤러 클래스나 메서드 위에 @CrossOrigin 주석을 달아 특정 출처의 요청을 허용합니다.
- 예를 들어, @CrossOrigin(origins = "http://localhost:4200")는 localhost:4200에서 오는 요청을 허용합니다.
- @CrossOrigin(origins = "*")는 모든 도메인에서 오는 요청을 허용합니다.
- 이 방법은 간단하지만, 여러 컨트롤러에 일일이 설정하기에는 비효율적입니다.
- 두 번째 방법: Spring Security 설정 사용:
- Spring Security의 SecurityFilterChain 빈을 생성하여 전역적으로 CORS 설정을 정의합니다.
@Bean
public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
// CORS 설정을 위한 CorsConfigurationSource 설정
http.cors(cors -> cors.configurationSource(new CorsConfigurationSource() {
@Override
public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
CorsConfiguration config = new CorsConfiguration();
// 허용된 출처 설정: localhost:4200
config.setAllowedOrigins(Collections.singletonList("http://localhost:4200"));
// 허용된 HTTP 메소드 설정: 모든 메소드 허용
config.setAllowedMethods(Collections.singletonList("*"));
// 자격 증명 허용 설정
config.setAllowCredentials(true);
// 허용된 헤더 설정: 모든 헤더 허용
config.setAllowedHeaders(Collections.singletonList("*"));
// 설정의 최대 유효 시간 설정: 3600초 (1시간)
config.setMaxAge(3600L);
return config;
}
}))
// HTTP 요청에 대한 권한 설정
.and().authorizeHttpRequests()
// 인증이 필요한 엔드포인트 설정
.requestMatchers("/myAccount", "/myBalance", "/myLoans", "/myCards", "/user").authenticated()
// 모든 사용자가 접근 가능한 엔드포인트 설정
.requestMatchers("/notices", "/contact", "/register").permitAll()
// 폼 로그인 설정
.and().formLogin()
// HTTP 기본 인증 설정
.and().httpBasic();
return http.build();
}
- 이 설정을 통해 특정 출처에서 오는 요청, 허용된 HTTP 메서드, 허용된 헤더, 인증 정보 허용 여부 등을 전역적으로 설정할 수 있습니다.
- MaxAge 설정을 통해 브라우저가 CORS 설정을 일정 시간 동안 캐시하도록 할 수 있습니다.
Pre-flight 요청:
- 교차 출처 요청이 발생하면, 브라우저는 먼저 Pre-flight 요청을 보내 서버에 CORS 정책을 확인합니다.
- 서버가 요청을 허용하면, 브라우저는 실제 요청을 보냅니다.