CORS-2021.12.12

Jonguk Kim·2021년 12월 12일
0

CS

목록 보기
8/9

1. CORS (Cross-Origing Resource Sharing) 란?

교차 출처 리소스 공유 (다른 출처의 리소스를 공유)
여기서 말하는 출처는 protocol, host, port를 합친 것을 의미

1-1. 출처 구분

1-2. SOP(Same-Origin Policy), 동일 출처 정책이란?

웹 생태계의 보안 정책으로 "같은 출처에서만 리소스를 공유할 수 있다"라는 정책

  • Postman이나 ARC로 API 테스트를 했을 때는 동일 출처이기 때문에 문제가 없다.
    하지만 React App과 Back Spring App을 돌리면 다음과 같은 문제가 발생한다.
    => Spring App의 Port는 8080인데 React App은 3000번 Port를 사용하기 때문에 브라우저에서 다른 출처를 허용하지 않아 발생하는 문제

  • 이러한 SOP 정책이 등장한 이유는 서로 다른 두 개의 어플리케이션이 마음대로 소통할 수 있다면, 보안상 매우 위험하기 때문이다. 브라우저의 개발자 도구창만 열어봐도 어떤 서버와 통신하는지, 리소스의 출처가 어딘지 쉽게 열람할 수 있기 때문에, 다른 출처의 어플리케이션이 서로 통신하는 것에 제약이 없으면, CSRF나 XSS와 같은 공격으로 정보 탈취가 쉬워진다.

  • 하지만 웹에서는 다른 출처의 리소스를 가져와 사용하는 일이 빈번하다.
    따라서 몇 가지 예외 조항을 두고 출처가 다른 리소스 요청도 허용할 수 있도록 해주었는데, 그것이 바로 CORS 정책을 지킨 리소스 요청이다.

  • 출처를 비교하는 곳은 사실 서버가 아니라 브라우저에서 구현된다.
    그래서 CORS 정책을 위반하는 요청을 하더라도 서버에서는 정상적으로 응답을 하지만, 브라우저에서 그 응답을 분석하고 출처를 비교하여 CORS 정책에 위반된다면 해당 응답을 버려버린다.
    => 이 문제를 해결하기 위해서는 Back이나 Front 둘 중에 한 군데에서 CORS 설정을 해주면 된다.

1-3. Simple Request

단순 요청 방법은 서버에게 그냥 바로 요청을 보내는 방법이다.

  • 서버에 API를 요청하고 서버에서는 Access-Control-Allow-Origin 헤더를 포함한 응답을 브라우저에게 보내면 브라우저는 해당 헤더를 확인하고 CORS를 수행할지 판단한다.

  • Simple Request의 조건은 아래와 같다.

    • 요청 메서드(method)는 GET, HEAD, POST 중 하나여야 한다.
    • Accept, Accept-Language, Content-Language, Content-Type, DPR, Downlink, Save-Data, Viewport-Width, Width를 제외한 헤더를 사용하면 안된다.
    • Content-Type 헤더는 application/x-www-form-urlencoded, multipart/form-data, text/plain 중 하나를 사용해야 한다.

=> 이 조건들은 REST API를 사용한다면 만족하기 어렵다
( 많은 REST API들이 Content-Type을 application/json로 사용하기 때문이다 )

1-4. Preflight Request

예비 요청을 먼저 보내는 방법은 예비 요청을 보내서 안전한지 판단한 후 본 요청을 보내는 방법이다.

  • OPTIONS 메서드로 서버에 예비 요청을 보낸 다음 서버는 응답으로 Access-Control-Allow-Origin 헤더를 포함한 응답을 브라우저에 보낸다.

  • 브라우저는 Access-Control-Allow-Origin 헤더를 확인해서 CORS 동작을 수행할지 판단한다.
    후에 확인이 완료되었다면 본 요청인 GET 요청을 통해 리소스를 받아온다.

1-5. SpringBoot CORS 에러 해결

  • 스프링 부트에서 CORS를 해결하는 방법은 4가지 정도가 있다.

    • Filter
    • CrossOrigin
    • WebMvcConfigure
    • Spring Security corsConfigurationSource
  • Spring Security corsConfigurationSource

public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    // ... 중략 
   
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // cors설정 추가
        http
                .cors()
                .configurationSource(corsConfigurationSource());

       // ... 중략
    }

    // ... 중략

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.addAllowedOrigin("http://localhost:3000"); // local 테스트 시
        configuration.addAllowedMethod("*");
        configuration.addAllowedHeader("*");
        configuration.addExposedHeader("Authorization");

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}
  • addAllowedOrigin : 허용 출처 설정해주기 -> 교차 출처를 허용할 출처를 적어준다 (Front 출처)
  • addAllowedMethod : 요청 시 오는 Http Method 허용을 말한다. -> 모두 허용
  • addAllowedHeader : 헤더 허용 -> 모두 허용
  • addExposedHeader : 노출시킬 헤더 -> 응답 시에 프론트에서 받았을 때 노출될 헤더를 설정
profile
Just Do It

0개의 댓글