[프로그래밍] 문제 해결

[SPRING] CORS 해결

JHVan 2024. 4. 24. 18:22

CORS란?

https://aws.amazon.com/ko/what-is/cross-origin-resource-sharing/

aws 에 누구보다 잘 정리된 글이 있다.

 

CORS란 무엇입니까? - 교차 오리진 리소스 공유 설명 - AWS

크로스 오리진 리소스 공유(CORS)는 애플리케이션을 통합하기 위한 메커니즘입니다. CORS는 한 도메인에서 로드되어 다른 도메인에 있는 리소스와 상호 작용하는 클라이언트 웹 애플리케이션에

aws.amazon.com

요컨데, (❗)CORS는 CSRF를 겨냥한 '보안' 정책이다. 다 열수록 편하지만 보안에 취약해진다.

 

WebConfig 로 해결하기

@Configuration
    @EnableWebMvc
    public class WebConfig implements WebMvcConfigurer {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")          		
                    .allowedOrigins("http://localhost:3000") // 허용할 출처
                    .allowedMethods("GET", "POST","PATCH","DELETE") // 허용할 HTTP method					
                    .allowCredentials(true) // 쿠키 인증 요청 허용                  
                    .maxAge(3000); // 원하는 시간만큼 pre-flight 리퀘스트를 캐싱
        }
    }

서버에서 이렇게 구체적으로 허용할 Origin 들을 명시해주면 허용된다.

 

와일드 카드 활용하기.

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();

        configuration.setAllowedOriginPatterns(Arrays.asList("*"));
        configuration.setAllowedMethods(Arrays.asList("*"));
        configuration.setAllowedHeaders(Arrays.asList("*"));
        configuration.setExposedHeaders("*"));
        configuration.setAllowCredentials(true);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

*<- 이걸 '와일드카드' 라고 한다. "와일드카드 이용해 '해결!' 해줬습니다."
이러면 크롬의 피와 땀으로 만든 보안은 활짝 열어줬지만 CORS 모르는 사람한텐 되게 있어보인다.

근데 AllowedOriginPatterns 에 와일드카드 쓰면 localhost 간 요청이 아니면 대부분 막힌다.

 


 웹 사이트에서 로컬로 보내는데? 에러


크롬은 chrome://flags/#block-insecure-private-network-requests 에서 블록 해제

엣지는 edge://flags/#block-insecure-private-network-requests

익스플로러는 애초에 막지도 않는다고 한다. 소문엔 CORS 정책 자체가 없다던데(?)




preflight 요청 

 

    public class WebConfig implements WebMvcConfigurer {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    .allowedOrigins("http://localhost:3000", "http://nadainma.com") // 허용할 출처
                    .allowedMethods("GET", "POST","PATCH","DELETE","OPTIONS") //<- 여기에요 여기보세요
                    .allowCredentials(true) // 쿠키 인증 요청 허용
                    .maxAge(3000); // 원하는 시간만큼 pre-flight 리퀘스트를 캐싱
        }
    }

허용할 메소드에 OPTIONS 추가하면 된다.

   public class WebConfig implements WebMvcConfigurer {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    .allowedOrigins("http://localhost:3000","http://nadainma.com") // 허용할 출처
                    .allowedMethods("GET", "POST","PATCH","DELETE","OPTIONS") // 허용할 HTTP method
                    .exposedHeaders("Authorization") //header 노출
                    .allowedHeaders("Authorization") // 요청 헤더 중 서버에서 허용하는 헤더
                    .allowCredentials(true) // 쿠키 인증 요청 허용
                    .maxAge(3000); // 원하는 시간만큼 pre-flight 리퀘스트를 캐싱
        }
    }

exposedHeaders 와 allowedHeaders 는 와일드카드 "*" 사용해도 요청 자체가 거절되진 않는다.

 

데이터 수준이 엄청 작은 초기 프로젝트시
초창기 간단한 수준의 요청은 cors 설정 없이도 되더라. 
구체적인 기준은 찾아봐도 알려진게 없었다.

내가 아무 CORS 설정 없이 날린건 "hello cors!" 였고, 브라우저에서 응답을 확인 할 수 있었다


크롬 확장 프로그램 중에 헤더에 와일드카드를 넣어주는 친구가 있다.
처음에도 말했지만 와일드카드는 어지간하면 빠꾸당하는데,
위에서 말한 아주 가벼운 수준(?) 의 요청만 가능하다.


휴우먼 에러


보통 CI/CD 전에 CORS 를 해결할 일이 많기 때문에, 배포 서버에 빌드 및 재배포를 안한 상태에서 코드만 열심히 이래저래 건들여보게 된다.
webConfig 잘 설정 했다면, 된다. CORS 에러가 나타났다면, 혹시 내가 빌드 및 재배포를 로컬에서만 한 게 아닌지, 혹은 WebConfig만 확인하고

SecurityFilterChain 에서한 CORS 설정을  잘못한 게 아닌지 확인해보자.