티스토리 뷰

728x90
반응형

브라우저에 출력되는 웹 문서는 웹문서의 동일한 출처로부터만 리소스를 가져올 수 있는 정책을 가지고 있었습니다. 예전에 하나의 웹문서가 여러 도메인으로부터 리소스를 요청하는 웹 문서는 금지되었다고 합니다. 하지만, 현대 웹 문서에는 여러 도메인으로부터 리소스를 요구하는 상황이 많아졌습니다. CORS 정책은 출처가 다른 도메인의 웹문서에게 리소스에 대한 접근권한을 설정하는 정책입니다. 이번 포스팅에서는 서버 사이드 애플리케이션인 Springboot에서 CORS 정책을 활성화하는 방법에 대해 알아보겠습니다.

CORS 정책 개요

CORS(=Cross Origin Resource Sharing)은 출처가 다른 웹 문서에게 리소스 접근을 제어하는 정책입니다. 여기서 출처(=Origin)란 프로토콜, 도메인, 포트를 말합니다. 동일 출처라는 뜻은 도메인 주소가 동일하다는 의미입니다.

CORS 동작 방식

CORS 정책이 적용된 브라우저는 서버로 HTTP 요청을 전송할 때, simple request 또는 preflighted request 방식으로 요청을 보냅니다. 
Simple Request는 요청을 보낼 때 헤더에 출처(Origin)를 포함하여 전송한 후, 수신받은 응답 값에 Access-Control-Allow-Origin 값을 확인하여 CORS 정책을 확인하는 방식입니다.

Preflight Request는 HTTP OPTIONS 메서드를 이용하여 리소스에 접근이 가능한지 서버에게 확인 요청을 전송한 후, 응답받은 결과에 따라, 실제 리소스 요청을 전송하는 방식입니다.

CORS 정책 제어

CORS 정책은 브라우저에서는 요청이 기본적으로 막혀있고, 서버 사이드에서는 출처가 다른 요청에 대하여 리소스 접근을 거부할 수 있습니다. 

Springboot에서 CORS 정책 설정하기

스프링부터에서 CORS 정책을 설정하여 요청 출처에 대해 리소스 접근을 제한할 수 있습니다. springboot cors 정책 설정 테스트 예제는 git repository를 clone 받은 뒤, complete 폴더의 프로젝트 빌드 및 실행해보시면 확인하실 수 있습니다.

git clone https://github.com/spring-guides/gs-rest-service-cors.git

스프링 부트에서 @CrossOrigin 어노테이션을 활용하면, 메서드에 CORS 정책을 설정할 수 있습니다.

@RestController
public class GreetingController {

	private static final String template = "Hello, %s!";

	private final AtomicLong counter = new AtomicLong();

	@CrossOrigin(origins = "http://localhost:8080")
	@GetMapping("/greeting")
	public Greeting greeting(@RequestParam(required = false, defaultValue = "World") String name) {
		System.out.println("==== get greeting ====");
		return new Greeting(counter.incrementAndGet(), String.format(template, name));
	}

	@GetMapping("/greeting-javaconfig")
	public Greeting greetingWithJavaconfig(@RequestParam(required = false, defaultValue = "World") String name) {
		System.out.println("==== in greeting ====");
		return new Greeting(counter.incrementAndGet(), String.format(template, name));
	}
}

/greeting은 출처가 http://localhost:8000에 대해 리소스 접근을 허용하고, /greeting-javaconfig는 아래 Global CORS 설정으로 http://localhost:9001에 대해서만 리소스 접근을 허용하고 있습니다.

@Bean
public WebMvcConfigurer corsConfigurer() {
   return new WebMvcConfigurer() {
      @Override
      public void addCorsMappings(CorsRegistry registry) {
         registry.addMapping("/greeting-javaconfig").allowedOrigins("http://localhost:9001");
      }
   };
}

CORS 정책 적용 여부 확인

localhost:8080과 localhost:9001 서버를 각각 구동한 후, localhost:8080 서버로 /greeting과 /greeting-javaconfig URL을 요청하여 리소스를 정상적으로 가져오는지 확인해보겠습니다.

웹문서에서 HTTP 요청을 전송하기 위해 AJAX로 리소스를 요청하는 스크립트를 작성합니다.

//index.html
<!DOCTYPE html>
<html>
    <head>
        <title>Hello CORS</title>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
        <script src="hello.js"></script>
    </head>

    <body>
        <div>
            <p class="greeting-id">The ID is </p>
            <p class="greeting-content">The content is </p>
        </div>
        <div>
            <p class="greeting-id-javaconfig">The JavaConfig ID is </p>
            <p class="greeting-content-javaconfig">The JavaConfig content is </p>
        </div>
    </body>
</html>
// app.js
$(document).ready(function() {
    $.ajax({
        url: "http://localhost:8080/greeting"
    }).then(function(data, status, jqxhr) {
       $('.greeting-id').append(data.id);
       $('.greeting-content').append(data.content);
       console.log(jqxhr);
    });

    $.ajax({
            url: "http://localhost:8080/greeting-javaconfig"
        }).then(function(data, status, jqxhr) {
           $('.greeting-id-javaconfig').append(data.id);
           $('.greeting-content-javaconfig').append(data.content);
           console.log(jqxhr);
        });
});

localhost:9001 서버에 접근하면, greeting-javaconfig에 대한 리소스는 가져오지만, greeting 요청에 대한 리소스는 거부되어 HTML 문서에 출력되지 않습니다. 이를 통해 CORS 정책이 잘 적용된 것을 확인할 수 있습니다.

Springboot CORS 정책 테스트

 

728x90
반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함