나만의공부(이슈정리)

[Spring-boot] CORS , SOP 개념 및 설정

jay Joon 2021. 1. 24. 17:43

CORS , SOP

CORS 이슈는 개인 프로젝트 REST API 애플리케이션 개발을 하면서 겪었던 이슈이다.

그게 뭐예요 ...??!!

이때는 CORS 가 뭔지도 몰랐다 ㅎㅎ.

일단 CORS 와 SOP의 개념부터 알아보자.

SOP(Same Origin Policy)

일단 Spring-boot 의 기본적으로 아무것도 설정을 하지 않는다면 SOP 정책을 따른다.

 

그래서 SOP 가 무엇이냐면

자바스크립트 엔진 표준 스펙의 보안 규칙으로

같은 호스트, 같은 포트 , 같은 프로토콜 에서만 접근이 가능한 정책(Policy)이다.

 

그럼 SOP에서 Origin은 (같은 호스트, 같은 포트 , 같은 프로토콜)을 나타낸다고 보면 된다.

 

예를 들어보자면 Spring-boot로 아무런 세팅을 하지 않고 Application을 실행했을 때 서버의 포트는 8080이다.

하지만 React의 기본 포트는 3000이다.

Server URL 주소
Spring boot Appication http:/localhost:8080
React http:/localhost:3000

 

자 React(Front-end)에서 boot (Back-end)로 XMLHttpRequest를 사용하여 어떠한 자원을 요청했을 때

 

정책을 위반함(같은 포트가 아님)으로 다음과 같은 이슈를 만나 볼 것이다.

 

has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource

 

그럼 이 이슈를 해결하기 위해선 어떻게 해야 할까?

 

해당 이슈를 해결하는 방법은 많다.

 

하지만 이번 글에서는 Spring-boot 내에서 해결하는 방법만 다룰 것이다.

 

이제 계속 CORS를 알아보자.

CORS(Cross-Origin Resource Sharing)

위에서 살펴본 것처럼 기본 정책은 보안상 이유로 교차 HTTP 요청을 제한한다.

 

따라서 다른 웹 자원에 접근 하기 위해선 권한을 부여해야 한다.

 

그러한 메커니즘을 지원하는 것이 CORS(교차 출처 리소스 공유)이다.

 

CORS 동작방법

HTTP 요청 헤더에 Origin 출처를 서버에 전송하여

 

서버에서 Access-Control-Allow-Origin 안에 허용된 출처를 내려보내고

 

origin 필드와 Access-Control-Allow-Origin과 비교하여 허용할 요청인지 허용하지 않을 요청인지 확인한다.

img

더 자세한 내용은 https://developer.mozilla.org/ko/docs/Web/HTTP/CORS 에서 확인해주세요

 

 

 

자 그러면 이제 이슈 생성해보고 해결해보자.

@RestController
public class SampleController {
    @GetMapping("CORS")
    public String cors(){
        return "CORS";
    }
}

여기 간단한 RestController 가 있다. (이 서버는 8080 포트에 올릴 것이다.)

 

그리고 다른 서버(9999 port)에서 8080 포트로 XMLHttpRequest요청을 보내 보자.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>CORS</h1>
<script src="/webjars/jquery/3.5.1/dist/jquery.min.js"></script>
<script>
    $(function (){
        $.ajax("http://localhost:8080/CORS")
            .done(function (value){
                alert(value);
            })
            .fail(function (){
                alert("fail");
            });
    })
</script>
</body>
</html>

XMLHttpRequest 요청은 JQuery를 이용하여 ajax 요청으로 요청을 보낼 것이다.

 

 

 

 

image

 

이제 실행해보면 아직 서버 쪽에 아무런 설정을 하지 않아서 해당 이슈가 발생한다 

 

 

 

이슈를 해결하기 위해선 Back-end 서버에서 다음과 같은 설정을 진행해주면 된다.

@Controller
public class SampleController {
    @GetMapping("CORS")
    @CrossOrigin(origins = "http://localhost:9999")  //요청 자원을 허락할 origin
    @ResponseBody
    public String cors(){
        return "CORS";
    }

}

@CrossOrigin 애노테이션을 이용하면 된다.

 

이 방법으로 설정하게 되면 http://localhost:8080/CORS 요청이 들어왔을 때 Origin 이 달라도 자원을 줄 수 있다.

하지만 해당 방법에서는  컨트롤러에서 맵핑 하고 있는 "/CORS" 에서만 적용된다.

 

따라서 해당 프로젝트의 Controller에서 전역적으로 사용할

 

Origin을 등록하고 싶다면 WebMvcConfigurer 이용하여  아래의 예제처럼 설정해주면

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("http://localhost:9999");
    }
}
 

진행하고 있는 모든 요청에 설정을 적용할 수 있다.

 

 

 

 

본문에 오류가 존재하거나 질문사항이 있다면 댓글로 남겨주세요!

 

감사합니다.