나의상황
CORS는 정말 해결해도해도 계속 문제가 생긴다. 완벽히 파훼법을 찾았다고 생각했었는데 security를 끼니 또또또 문제가 생겼다.
( security 증말 까다롭다;; )
먼저 이를 해결하기 위해서는 CORS 개념과, SOP 정책에 대해서 정확히 알아야 한다.
동일 출처 정책이라고도 불리며, 웹 브라우저의 보안 정책이다.
먼저 SOP(Same Origin Policy) 정책은 단어 그대로 동일한 출처에 대한 정책을 말한다. 그리고 이 SOP 정책은 '동일한 출처에서만 리소스를 공유할 수 있다.
뭐.. 이정책이 왜 생겨서 우릴 괴롭히나 싶지만...
SOP 정책의 역할
XSS (Cross-Site Scripting) 및 CSRF (Cross-Site Request Forgery) 공격을 방지한다..
필요한 정책이니 원망하지는 맙시다구요
참고로 origin의 기준은 port번호까지 !!
근데 죽은 IE는 port번호달라도 같은 origin으로 쳐줬다네요
( 상개발자인 나에겐 오히려 좋아 )
안타깝게도 , 백엔드와 프론트엔드를 둘 다 같은 서버에서 실행시킨다해도 둘은 다른포트에서 실행될것이기 때문에 둘은 같은 origin이 아니다.
그래서 우리가 연동할때 맨날 CORS오류를 겪는것임..
교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 브라우저가 자신의 출처가 아닌 다른 어떤 출처(도메인, 스킴 혹은 포트)로부터 자원을 로딩하는 것을 허용하도록 서버가 허가 해주는 HTTP 헤더 기반 메커니즘이다.
<정리> 하자면..
우리가 생각하는 CORS 에러는 사실 해결책이였던것.
SOP 정책 으로 인해 생기는 문제가 아래와 같이 나오는 CORS 에러 이고
Access to XMLHttpRequest at 'http://localhost:8080/api/data' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
해결하기 위한 방안이 CORS설정 인것!!
보통 spring을 통한 개발을 할때 아래와 같이public class WebConfig implements WebMvcConfigurer
를 구현하여 CORS를 허용한다.
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("https://www.example.com") // 허용할 프론트엔드 주소
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*") // 모든 헤더 허용
.allowCredentials(true); // 쿠키 전송 허용
}
}
BUT
...
Spring Security를 사용하면 보안 설정 때문에 CORS 설정이 무시된다. (WTF)
그래서 webconfig 구현을 통해 전역으로 CORS설정 해줬으니 안심^^ 하다가.. 나중에 씹힌다는걸 알고 분노한 경험이 있다.
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(List.of("http://localhost:3000")); // 내가 허용해주고자하는 다른 origin 주소
configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
configuration.setAllowedHeaders(List.of("*"));
configuration.setAllowCredentials(true);
configuration.setExposedHeaders(List.of("access", "Set-Cookie"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
필자의 시행착오 ( 계속해서 추가될 예정 )
configuration.setAllowedOrigins(List.of("http://localhost:3000"));
→ 이거 *로 하면 씹히는 경우 있음
configuration.setExposedHeaders(List.of("access", "Set-Cookie"));
→ 인증/인가 쿠키 사용할때 이 부분 꼭 써줘야함. 커스텀헤더명이 access인지 뭐 Authroization인지 뭐.. 다른건지 잘 확인해주자
참고