CORS 개념, spring security, react에서 해결방법

박해인·2025년 2월 13일
1

Web

목록 보기
2/3

나의상황
CORS는 정말 해결해도해도 계속 문제가 생긴다. 완벽히 파훼법을 찾았다고 생각했었는데 security를 끼니 또또또 문제가 생겼다.
( security 증말 까다롭다;; )

먼저 이를 해결하기 위해서는 CORS 개념과, SOP 정책에 대해서 정확히 알아야 한다.

1. SOP 정책이란?

동일 출처 정책이라고도 불리며, 웹 브라우저의 보안 정책이다.
먼저 SOP(Same Origin Policy) 정책은 단어 그대로 동일한 출처에 대한 정책을 말한다. 그리고 이 SOP 정책은 '동일한 출처에서만 리소스를 공유할 수 있다.

뭐.. 이정책이 왜 생겨서 우릴 괴롭히나 싶지만...

SOP 정책의 역할
XSS (Cross-Site Scripting) 및 CSRF (Cross-Site Request Forgery) 공격을 방지한다..

필요한 정책이니 원망하지는 맙시다구요

참고로 origin의 기준은 port번호까지 !!
근데 죽은 IE는 port번호달라도 같은 origin으로 쳐줬다네요
( 상개발자인 나에겐 오히려 좋아 )

안타깝게도 , 백엔드와 프론트엔드를 둘 다 같은 서버에서 실행시킨다해도 둘은 다른포트에서 실행될것이기 때문에 둘은 같은 origin이 아니다.
그래서 우리가 연동할때 맨날 CORS오류를 겪는것임..

2. 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설정 해줬으니 안심^^ 하다가.. 나중에 씹힌다는걸 알고 분노한 경험이 있다.

Security에서의 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;
    }

필자의 시행착오 ( 계속해서 추가될 예정 )

  1. configuration.setAllowedOrigins(List.of("http://localhost:3000")); → 이거 *로 하면 씹히는 경우 있음

  2. configuration.setExposedHeaders(List.of("access", "Set-Cookie"));
    → 인증/인가 쿠키 사용할때 이 부분 꼭 써줘야함. 커스텀헤더명이 access인지 뭐 Authroization인지 뭐.. 다른건지 잘 확인해주자


참고

profile
갓생살고싶어라

0개의 댓글