1. 문제 상황

localhost:3000에서 localhost:8000/members 로 회원가입(POST) 요청을 보내고 있었음

try{
    const response = await fetch('<http://localhost:8080/members>',
        {
            method: 'POST',
            headers: {
                'content-Type': 'application/json',
            },
            body: JSON.stringify({
                email: emailInput,
                nickname: nicknameInput,
                password: passwordInput
            }),
        }
        
    );
    if(response.ok){
        console.log('회원가입 성공');
    }else{
        console.log('회원가입 실패: ', response.status);
    }
} catch (error){
    console.error('회원가입 실패', error);
}
@Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("<http://localhost:3000>"));
        configuration.setAllowedMethods(Arrays.asList("GET","POST","PATCH","DELETE"));      
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**",configuration);
        return source;
    }

다음과 같은 시큐리티 설정으로 localhost:3000의 요청을 허용하고 있었으나 CORS가 발생함

2. 문제 원인

요청 오리진, 메서드 뿐만 아니라 허용할 요청 헤더까지 까다롭게 전부 명시해 주어야 한다는 사실을 배움

현재의 요청에는 헤더에 'content-Type': 'application/json’ 이 명시되어 있었기 때문에, 서버에서 이러한 헤더를 허용하도록 명시하여 주어야 함

브라우저는 preflight 요청을 통해 서버가 이러한 헤더를 허용하는지 확인하는데, 서버에 허용 헤더 목록에 명시돼 있지 않다면 요청은 차단함

3. 문제 해결

다음과 같이 시큐리티 설정에 허용 헤더를 명시함으로서 문제가 해결되었음

@Bean
CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(Arrays.asList("<http://localhost:3000>"));
    configuration.setAllowedMethods(Arrays.asList("GET","POST","PATCH","DELETE"));
    configuration.setAllowedHeaders(Arrays.asList("Authorization", "Content-Type"));
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**",configuration);
    return source;
}