Spring Boot CORS header 'Access-Control-Allow-Origin' 에러
반응형

Spring Boot를 사용하면서 Rest API 방식을 구현하다보면, Postman같은 프로그램에서는 잘만 작동되는데 실제 실행에서는 에러가 발생할 때가 있다.

React (Node.js) : http://localhost:3000

Spring boot : http://localhost:8081

두 Origin 간에 프로토콜, 포트, 호스트가 같아야 Same - Origin - Policy 정책을 만족시키는데, 실제로 Origin이 다른 경우가 허다하기 때문에 서버측에서 CORS를 이용하여야 한다.

위 에러는 CORS(Cross-Origin Resource Sharing)를 하기 위해 header에 보내는 키(Access-Control-Allow-Origin)이 없다는 뜻이다.

우선 나는 검색을 통해 나온 메소드나 컨트롤러 위에 `@CrossOrigin("*")` 를 추가하는 방법이나, WebConfig에서 addCorsMappings를 설정하는 방법으로는 해결할 수 없었다.

그렇다면 Spring Boot에서는 어떻게 해야 할까.

검색을 통해 Spring Security를 살펴보면, CORS에 대한 항목을 확인할 수 있다.

링크 : https://docs.spring.io/spring-security/site/docs/current/reference/html5/

가장 간편한 방법은 CorsConfigurationSource를 사용하여 CorsFilter를 정의하는 방법이다.

기존에 Jwt를 활용한 토큰 인증 방식에서 사용한 필터와 함께 사용할 수 있다.

없으면 Config 클래스파일을 정의하면 된다.

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
    @Override
	protected void configure(HttpSecurity httpSecurity) throws Exception {
        //HTTP 설정(기존에 사용하던 설정에 추가하면 된다)
        httpSecurity
        /*.
        .*/
          .cors()  //cors 필터 등록
       /*.
        .*/
    }
    
     @Bean
    CorsConfigurationSource corsConfigurationSource(){
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("Origin URL 등록" ));
        configuration.setAllowedMethods(Arrays.asList("사용할 CRUD 메소드 등록"));
        configuration.setAllowedHeaders(Arrays.asList("사용할 Header 등록"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}

CORS를 지원하기 위해서는 날아오는 preflight 요청에 다음과 같은 응답 헤더를 무조건 한 개 이상 포함해야 한다.

`Access-Control-Allow-Methods` -> 사용할 CRUD 메소드 (GET, POST, PUT, DELETE ...)

`Access-Control-Allow-Headers` -> 사용할 헤더 목록

`Access-Control-Allow-Origin` -> Orign 주소 등록

이때 CorsConfiguration의 set메소드는 List의 매개변수를 받기 때문에 `"GET", "POST", "PUT", "DELETE" `와 같은 형식으로 원하는 조건에 맡게 parameter를 넘겨주면 된다.

반응형