Spring Boot CORS Error 해결

Luna Park·2022년 7월 4일
1
post-thumbnail

Spring Boot로 백엔드 서버를 구축하고 서버에 배포한 이후, 프론트 팀에서 header에 authorization으로 jwt 토큰을 붙여서 요청을 보내면 다음과 같은 CORS 에러가 뜬다는 피드백을 주었다.

Access to fetch at 'https://도메인/엔드포인트' from origin 'https://호출한도메인' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

이미 아래 코드에서 CORS 처리를 해주었다고 생각했는데, 위와 같은 오류가 발생하니 머리가 새하얘졌다.

WebAppConfiguration.java

@Configuration
public class WebAppConfiguration implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("http://localhost:3000");
    }
}

Solution

왜 이런 error가 발생했는지를 알아보기 전에 해결 방법을 먼저 설명하자면

내가 개발하는 백엔드의 경우 Keycloak과 연동하여 사용했기 때문에 KeycloakWebSecurityConfigurerAdapter를 상속받는 클래스에서 에러를 해결해주었고, 그냥 Spring Boot를 이용하는 경우에는 WebSecurityConfigurerAdapter를 상속받는 클래스에서 코드를 추가해주면 될 것 같다.

cors().and()
authorizeRequests().requestMatchers(CorsUtils::isPreFlightRequest).permitAll()

전체 코드를 보자면 다음과 같다.

@Configuration
@EnableWebSecurity
public class KeycloakConfig extends KeycloakWebSecurityConfigurerAdapter {
	
    {...}

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        
        http.cors().and();
        
        http.authorizeRequests()
                .requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
                {...}
                .anyRequest().permitAll();
        http.csrf().disable();
    }

  	{...}

}

Error의 원인

CORS에서 preflight이란 브라우저가 본 요청을 보내기 전의 예비 요청과 같은 개념이라고 한다.
브라우저는 cross-origin 요청을 전송하기 전에 OPTIONS 메서드로 preflight하여 지원하는 메서드를 요청하고, 서버의 "허가"가 떨어지면 실제 요청을 보내도록 한다.

preflight request에 대해서 서버가 error를 뱉어내고 있기에, preflight request에 대해 인증을 하지 않고 요청을 모두 허용하게 해주었다.

profile
Happy Ending Is Mine

0개의 댓글