💡 Origin : Protocol + Host + Port
- 같은 프로토콜 및 호스트 및 포트를 사용할 경우, 그 뒤의 요소는 다르더라도 같은 출처로 인정. (ex: https://www.domain.com:3000)
- 위의 세가지 중 하나라도 출처와 다를 경우, 브라우저는 접속을 차단. ( 출처 비교 및 차단은 브라우저에서. 즉, 서버가 아닌 브라우저에 구현된 스펙. )
- 모두 차단할 수 없기 때문에 몇 가지 예외 조항을 두고, 다른 출처의 요청이라도 허용할 수 있도록 설정. 그 중 하나가 CORS 정책을 지킨 요청.
( 즉, SOP 정책을 위반 해도, CORS 정책에 따르면 다른 출처의 요청도 허용 )
SOP(Same Origin Policy) : 동일한 출처에 대한 정책. 동일한 출처에서만 리소스를 공유 가능.
💡 Cross-Origin Resource Sharing : 교차 출처 리소스 공유
- 클라이언트가 보내준 Origin : 출처
- 서버가 보내준 Access-Control-Allow-Origin : 접근 허용된 출처 URL
- 브라우저에서 비교를 통해 유효 하지 않다면, 서버가 전송한 응답을 클라이언트에게 전달 하지 않고 버림.
- 즉, 서버에서 Access-Control-Allow-Origin 헤더에 허용할 출처를 기재해서 클라이언트에 응답.
💡 Preflight Request : 예비 요청
- 브라우저는 요청을 보낼 때 바로 보내지 않고, 예비 요청을 보내 서버와 잘 통신 되는지 확인 후 본 요청을 보냄.
- 즉, 예비 요청의 역할은 본 요청을 보내기 전에 브라우저가 안전한 요청인지 확인 하는 것.
- 예비 요청의 HTTP Method 는 GET 요청 및 POST 요청이 아닌, OPTIONS 요청이 사용 된다는 것이 특징.
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.cors().configurationSource(corsConfigurationSource());
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setMaxAge(MAX_AGE_TIME);
configuration.addAllowedOriginPattern("*");
configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"));
configuration.addAllowedHeader("*");
configuration.addExposedHeader(AUTHORIZATION_HEADER);
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
- 특정 경로에 대해 CorsConfiguration 객체에서 설정한 값을 CorsConfigurationSource 인터페이스를 구현한 UrlBasedCorsConfigurationSource에 적용시킨다. 여기서는 모든 경로로 설정되어 있다.
- Spring Security의 CORS 설정에서는 CorsConfigurationSource 인터페이스의 구현체를 파라미터로 받는 configurationSource가 있다. 여기에 설정한 UrlBasedCorsConfigurationSource 객체를 넣어주면 위에서 설정한 내용이 Spring Security에 적용된다.