Develop/Java

Cross-Origin 해결기

HaeYoung_12 2024. 10. 17. 18:01

프롤로그

지금은 졸업작품을 만들어야 하는 시즌, 나도 어김없이 팀원과 함께 리액트-스프링부트로 웹사이트 제작을 하고 있었는데.... 가장 무서운 오류가 걸려 버렸다!

그 이름은 바로 Cross-Origin

 

제발... 얌전히 잡혀주면 안되겠니.

 

시도한 것

 

블로그를 참고하여 다양한 시도를 진행했다.

1. 리액트에 설정

package.json에 proxy 설정

-> 실패

2. 리액트 http-proxy-middleware 설치후  setProxy.js 만들어 설정하기 

-> 실패

2. 스프링부트에 설정

@CrossOrigin 설정

-> 했음 그러나 여전히 안됨

3. WebMvcConfigure 구현해서 전역 CrossOrigin 설정하기

-> 안됨..

 

4...5...6..-> 다안됨..

 

생각해보니 너무 무작정 블로그만 보고 따라하는 것 같아서 저번에 썼던 코드(웹사이트 구현할때 참고한 코드)랑 지금이랑 뭐가다른 비교하면서 생각해 보기로 했다.

 

1. 예전버전이랑 지금이랑 Cros 설정하는 방법이 다름

- 예전 방법 

 

Adds a CorsFilter to be used. If a bean by the name of corsFilter is provided, that CorsFilter is used. Else if corsConfigurationSource is defined, then that CorsConfiguration is used. Otherwise, if Spring MVC is on the classpath a HandlerMappingIntrospector is used.

→ corsFilter라는 이름의 빈이 제공되면 해당 CorsFilter가 사용됩니다. 그렇지 않으면 corsConfigurationSource가 정의된 경우 해당 CorsConfiguration이 사용됩니다. 그렇지 않으면 Spring MVC가 클래스 경로에 있는 경우 HandlerMappingIntrospector가 사용됩니다.

 

이 CrosConfig가 구현한 인터페이스 WebMvcConfigurer을 타고 올라가면

CrossConfiguration 이 나온다!

즉 cros()를 등록하면 자동으로 @Configuration으로 등록한 CrosConfig 파일을 찾아 규칙을 적용한 것이다.

 

하지만 이번에 구현할때는 스프링 버전이 올라가면서 빨간줄이 뜨면서 이런 메시지가 떴다.

cors()' is deprecated since version 6.1 and marked for removal

 

정확히 몰라서 ChatGPT한테 물어봤더니 이런 대답이 돌아왔다.

스프링 보안(Spring Security) 6.1 버전에서는 cors() 메서드가 더 이상 권장되지 않으며, 사용을 중단(Deprecated)하도록 변경되었습니다. 이 경우 새로운 방식으로 CORS 설정을 추가해야 합니다. 스프링 보안 6.1 이후 버전에서는 **CorsConfigurationSource**를 설정하는 방법을 권장하고 있습니다.

 

그래서 cros(Customizer.withDefault())를 넣어준뒤 CorsConfigurationSource를 구현했더이 더이상 Crossorigin 오류가 생기지 않았다!

 

아래는 구현한 코드이다

@Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        return http
                .cors(Customizer.withDefaults())
                .authorizeRequests(auth -> auth
                        .requestMatchers(
                                new AntPathRequestMatcher("/api/user/login"),
                                new AntPathRequestMatcher("/api/user/signup")
                        ).permitAll()
                        .anyRequest().authenticated())
                .logout(logout -> logout
                        .logoutSuccessUrl("/api/user/login")
                        .invalidateHttpSession(true)
                )

                .csrf(AbstractHttpConfigurer::disable)
                .build();

    }
    
    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(List.of("http://localhost:3000"));  // 허용할 출처
        configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE"));  // 허용할 메서드
        configuration.setAllowedHeaders(List.of("Authorization", "Content-Type"));  // 허용할 헤더
        configuration.setAllowCredentials(true);  // 인증 관련 설정 (쿠키 등)

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);  // 모든 경로에 CORS 설정 적용
        return source;
    }

 

또 다른 문제에 직면

 

이건 403에러가 떴다. 서버가 거부한것이다. Cors 설정도 했는데 왜 이러지 생각하다가,

뭔가 감으로 이 SecurityConfig 파일의 이부분을 바꿔 보았는데... 아래 파일에서 "/static/**"을 "/**"로 바꾸었더니 비로서 정상작동이 되었다. 

@Bean
public WebSecurityCustomizer configure() {
    return (web) -> web.ignoring()
            .requestMatchers(new AntPathRequestMatcher("/**"));

}
 

추가로 궁금한점

- CorsConfigurationSource말고 기존에 있던 Crossconfig 파일을 @Configuration 등록을 했더니 오류 없이 돌아간다.

둘의 차이가 뭔지 다음에 찾아 봐야겠다.