부트 개념과 활용-21.CORS(웹 MVC)


스프링 웹 MVC 11부: CORS

  • Cross-Origin Resource Sharing의 약자.
  • Single-Origin Policy를 우회하기 위한 표준 기술.

    SOP과 CORS

  • Single-Origin Policy - 같은 오리진에만 요청을 보낼 수 있다.
  • Cross-Origin Resource Sharing - 서로다른 오리진끼리 리소스를 쉐어할수 있는 방법을 제공하는 표준

Origin?

  • URI 스키마 (http, https)
  • hostname (whiteship.me, localhost)
  • 포트 (8080, 18080)

이 3가지를 조합한게 하나의 Origin.

기본적으로 SOP(Single-Origin Policy)가 적용된다.(오리진이 다른 경우 호츨을 못함)

하나의 Origin이 또다른 Origin를 호출할 수 없다.

REST API를 만약 로컬호스트 포트 8080를 사용하는 애플리케이션에서, 18080 포트에서 사용하는 애플리케이션으로 Ajax 호출 같은 것을 하려고 한다면 못한다. (=리소스를 가져오려고 한다면) (Cross-Origin Resource 에 위반이 되기 때문에)

CORS 사용하려면 이런 설정들을 해야하는데, 부트가 이런 빈 설정 등을 자동으로 해 준다. @CrossOrigin 어노테이션을 사용해 그냥 바로 활용이 가능하다.

스프링 MVC @CrossOrigin

https://docs.spring.io/spring/docs/5.0.7.RELEASE/spring-framework-reference/web.html#mvc-cors @Controller나 @RequestMapping에 추가하거나 WebMvcConfigurer 사용해서 글로벌 설정

실습

1-8080포트

@SpringBootApplication
@RestController
public class CorsApplication {

    @GetMapping("/hello")
    public String hello(){
        return "hello";
    }

    public static void main(String[] args) {
        SpringApplication.run(CorsApplication.class, args);
    }
}

2-18080 포트 application.properties

server.port=18080

index.html / jquery 의존성 추가 (webjar)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>CORS Test</title>
</head>
<body>
<h1>CORS TEST JAEUK</h1>
<script src="/webjars/jquery/3.4.1/dist/jquery.min.js"></script>
<script>
    $(function () {
        $.ajax("http://localhost:8080/hello")
        .done(function (msg) {
            alert(msg);
        })
        .fail(function (e) {
            alert("fail");
            console.log(e);
        })
    })
</script>
</body>
</html>

이상태로 18080 실행하면 fail이 뜬다.

(index):1 Access to XMLHttpRequest at ‘http://localhost:8080/hello’ from origin ‘http://localhost:18080’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

보이는대로 서버로부터 ‘Access-Control-Allow-Origin’ 헤더가 제공이 되지 않는다.
그래서 이 origin은 여기에 접속을 할 수 없다.
CORS 정책에 의해 차단이 된다.

이런 의미인데..
Access-Control-Allow-Origin 헤더가 어떤 origin이 나한테 접근이 가능한지 알려주는 헤더이다.
즉, 서버에서 이런 origin은 나한테 접근할 수 있다. 라는걸 알려줘야 한다는 뜻이다.

이걸 가능하게 하려면 메서드에 선언을 해도 되고,

    @CrossOrigin(origins = "http://localhost:18080")
    @GetMapping("/hello")
    public String hello(){
        return "hello";
    }

아니면 전역적으로 선언을 해야 한다면..

@Configuration
public class WebConfig implements WebMvcConfigurer {
    // 웹 관련된 설정파일은 WebMvcConfigurer 확장해서
    // 스프링 부트가 제공하는 스프링 MVC 기능을 전부 사용하면서 추가로 확장
    
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**") // 모든 패턴
                .allowedOrigins("http://localhost:18080"); // 18080 포트 허용
    }
}

웹 관련된 설정파일은 WebMvcConfigurer 확장해서
스프링 부트가 제공하는 스프링 MVC 기능을 전부 사용하면서 추가로 확장이 가능하다.

정상적으로 18080 포트에서 hello 가 뜨는 것을 확인할 수 있다.




© 2019. by jaeuk