부트 개념과 활용-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 가 뜨는 것을 확인할 수 있다.