[Spring Boot] CORS 적용하기

민채·2021년 8월 11일
5

SpringBoot

목록 보기
1/2

스프링 부트로 REST API 서버를 만들면 postman에서는 실행이 잘 되는데 프론트쪽에서 실행할 때 에러가 나는 경우가 있다.
나는 이번에 처음 겪어본 에러였는데 SOP 정책을 따르지 않아서 발생하는 문제였다.

SOP (Same Origin Policy)

SOP는 같은 Origin에만 요청을 보낼 수 있게 제한하는 보안 정책을 의미한다.
즉 같은 호스트, 같은 포트, 같은 프로토콜 에서만 접근이 가능한 것이다.

스프링 부트는 아무런 설정을 하지 않으면 SOP 정책을 따르게 된다.

백엔드인 스프링 부트는 http://localhost:8080 을 사용하였고,
프론트는 http://localhost:3000 을 사용하였다.
-> 두 Origin 간에 프로토콜, 포트, 호스트가 같아야 SOP 정책을 만족시키는데, Origin이 달라 해당 정책을 만족시키지 못하기 때문에 서버측에서 CORS를 이용하여야 한다.

CORS (Cross-Origin Resource Sharing)

CORS 란 서로 다른 Origin끼리 요청을 주고받을 수 있게 정해둔 표준이다.
위와 같이 백엔드와 프론트의 Origin이 다를 경우 사용해야 한다.

처음에 프론트가 보내준 에러는 아래 사진의 내용과 같다.

이 에러를 보고 CORS가 뭔지 찾아보고 여러 블로그를 보면서 해결 방법을 찾았는데 두 가지 방법이 있었다.

  1. CORS를 적용하고자 하는 Controller 위에 @CrossOrigin("*") 사용하는 것 -> 이 방법은 특정 컨트롤러의 url에만 적용이 된다.
  2. WebMvcConfigurer 인터페이스를 상속받아서 CORS를 적용하는 것 -> 아래 코드와 같이 작성하면 된다.
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
            .allowedOrigins("http://localhost:3000");
    }
}

나는 두 번째 방법을 선택하였고, 위의 사진에서 발생한 에러는 해결할 수 있었다.
하지만 다음 날 프론트쪽에서 또 CORS 관련 에러가 또 발생한다고 연락이 왔다😂

위와 같은 에러였는데, WebConfig에 .allowedMethods("*") 를 추가했는데도 해결되지 않았다..
그래서 찾아보니 Spring Security 관련해서 설정을 추가하면 됐었다. (Spring Security를 사용한다면 이 방법을 사용하면 될 것이다.)

@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
	// 추가
    httpSecurity.cors().configurationSource(request -> new CorsConfiguration().applyPermitDefaultValues());

    httpSecurity
        ....
        .authorizeRequests()
        .requestMatchers(CorsUtils::isPreFlightRequest).permitAll() // 추가
}

-> jwt 인증 방식을 사용하기 위해 WebSecurityConfigurerAdapter를 상속받아 만들었던 
WebSecurityConfig 클래스의 configure 메소드에 추가한 코드

이 두 줄을 추가하니 해당 에러는 사라졌다.

그런데!! 다음 날 또 밑의 사진처럼 에러가 발생한다고 연락을 해왔다..🤦‍♀️

delete 요청을 보내면 위와 같은 에러가 발생했는데 구글링을 해보니 내가 Spring Security 관련해서 이전에 추가했던
httpSecurity.cors().configurationSource(request -> new CorsConfiguration().applyPermitDefaultValues())
이 코드 때문이었다..

applyPermitDefaultValues() 메소드는 allowMethods를 따로 설정해 주지 않으면 default로 GET, HEAD, POST만 가지게 된다.
그래서 이걸 사용하지 않고 아래와 같이 코드를 수정해 GET, HEAD, POST 이외의 메소드도 추가해줘야 한다.

@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
    httpSecurity.cors().configurationSource(request -> {
        var cors = new CorsConfiguration();
        cors.setAllowedOrigins(List.of("http://localhost:3000"));
        cors.setAllowedMethods(List.of("GET","POST", "PUT", "DELETE", "OPTIONS"));
        cors.setAllowedHeaders(List.of("*"));
        return cors;
    });
    
    ....
    
}
  • setAllowedOrigins() : 허용할 URL
  • setAllowedMethods() : 허용할 Http Method
  • setAllowedHeaders() : 허용할 Header

이틀 정도 CORS 관련 에러 때문에 몇 시간을 날렸는지ㅠㅠㅠ 아무튼 이렇게 설정하니 이제는 에러가 발생하지 않는다!!👍

profile
코딩계의 떠오르는 태양☀️

1개의 댓글

comment-user-thumbnail
2022년 11월 14일

좋은 내용 감사합니다 :D

답글 달기