저번 포스팅에서는 CORS의 개념과 왜 사용하는지를 정리해보았습니다. https://velog.io/@seokhwan-an/CORS를 참고하시면 보실 수 있습니다.
이번 포스팅에서 CORS가 어떻게 동작하는지를 확인하고 이를 해결해보는 방법에 대해 알아보겠습니다.
앞선 포스팅에서 간단하게 정리했는데 CORS의 큰 원리는 클라이언트가 서버로 요청을 보낼 때 http message header 부분에 Origin에 자신의 출처를 보내고 서버는 응답으로 Access-Control-Allow-Origin에 허용된 출처를 보내주어 브라우저에서 이를 확인해 보내준 리소스의 유효성을 판단합니다. 간단해 보이지만 크게 2가지의 시나리오가 존재합니다.
1. Preflight Request
프리플라이트(Prefligt) 방식은 자주 접할 수 있는 시나리오 입니다. 간단하게 요약을 하면 클라이언트가 본 요청을 보내기 전에 예비 요청을 보내므로써 요청에 대한 응답이 유효한지를 파악하는 것입니다. 이 때에는 http 메소드 중에 OPTION 메소드가 활용됩니다.
💡OPTION 메소드
The HTTP OPTIONS method requests permitted communication options for a given URL or server. A client can specify a URL with this method, or an asterisk (*) to refer to the entire server.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS
OPTION 메소드는 주어진 URL 또는 서버에 대해 허용된 통신 옵션을 요청하는 메소드입니다.
위의 그림을 보면 알 수 있듯이 javascript에서 fetch API를 통해 브라우저에게 서버로부터 응답 리소스를 받아오라는 요청을 보내면 브라우저는 먼저 서버에게 예비요청을 보내고 예비요청에 대한 응답이 유효하다가 판단이 되면 본 요청을 보내서 서버로 부터 리소스를 받아오는 방식입니다.
OPTION 요청을 보내는 것은 특정 조건이 만족하지 않는 경우에 보내게 되는 것입니다.
2. Simple Request
단순 요청(simple request)은 예비요청을 보내지 않고 바로 서버로 요청을 보내어 서버로 부터 응답을 받고 브라우저에서 유효성을 파악하는 방법입니다. Preflight request와 큰 맥락은 같고 예비요청을 보내는 여부와의 차이가 있습니다.
simple request가 이루어지기 위해서는 앞선 언급한 조건들이 모두 만족하는 경우 입니다.
이제는 실제 개발에서 CORS를 해결하는 방법에 대해 설명하겠습니다. 저는 스프링을 이용하여 개발 학습을 진행하는 만큼 스프링에서 이용하는 CORS 해결방식을 제시하겠습니다.
@CrossOrigin(originPatterns = "허용할 출처")
@RestController
public class TestController {
@GetMapping()
public String test() {
return "test";
}
@RestController
public class TestController {
@GetMapping()
@CrossOrigin(originPatterns = "허용할 출처")
public String test() {
return "test";
}
단점으로는 controller가 많아지거나 method가 많아지면 사용해야할 어노테이션 수가 많아집니다.
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("허용할 출처")
.allowedMethods(HttpMethod.GET.name());
}
}
allowedOrigins에서는 허용한 출처를 정하는 것이고 allowedMethods에서는 허용할 http 매소드를 설정합니다.
이외에도 프록시 서버를 이용해서 CORS를 우회하는 방식이 있는데 이부분은 잘 이해가 되지 않아서 학습을 더한 이후에 추가해 놓겠습니다.
https://evan-moon.github.io/2020/05/21/about-cors/
https://steady-coding.tistory.com/616