( Cross-Origin Resource Sharing )
웹개발의 신입 신고식이라고 할 정도로 CORS 는 누구나 한 번 정도는 겪게 됨
다른 출처의 리소스 공유에 대한 허용/비허용 정책
Access to fetch at ‘https://myhomepage.com’ from origin ‘https://localhost:3000’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.
이 에러 메세지는 사실 브라우저의 SOP 정책에 따라 다른 출처의 리소스를 차단하면서 발생된 에러이며, CORS 는 다른 출처의 리소르를 얻기위한 해결 방안임
( SOP 정책을 위반해도 CORS 정책에 따르면 다른 출처의 리소스라도 허용함 )
: 출처
Origin : Protocol
+ Host
+ Port
를 모두 합친 URL
< URL 구성 요소 >
https://www.domain.com:3000/user?query=name&page=1#first
-------|--------------|----|----|-----------------|-----
Protocol Host Port Path Query string Fragment
= Scheme
Protocol
, Scheme
: http, https, ftp, telnet
Host
: 사이트 도메인
Port
: 포트 번호
Path
: 사이트 내부 경로
Query string
: 요청의 key 와 value 값
Fragment
: 해시 태그
( Same-Origin Policy ) - 동일한 출처에 대한 정책
동일한 출처 서버에 있는 리소스를 가져올 수 있지만, 다른 출처 서버에 있는 리소스는 가져올 수 없음
: 예비 요청
브라우저는 요청을 보낼 때 한번에 바로 보내지 않고, 먼저 예비 요청을 보내 서버와 잘 통신되는지 확인한 후 본 요청을 보냄
( OPTIONS 메서드 사용 )
: 단순 요청
예비 요청을 생략하고 바로 서버에 직행으로 본 요청을 보낸 후, 서버가 이에 대한 응답의 헤더에 Access-Control-Allow-Origin 헤더를 보내주면 브라우저가 CORS 정책 위반 여부를 검사하는 방식
GET
, HEAD
, POST
메서드만 가능서버에서 Access-Control-Allow_Origin 헤더 세팅하기
// 스프링 서버 전역적으로 CORS 설정
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:8080", "http://localhost:8081") // 허용할 출처
.allowedMethods("GET", "POST") // 허용할 HTTP method
.allowCredentials(true) // 쿠키 인증 요청 허용
.maxAge(3000) // 원하는 시간만큼 pre-flight 리퀘스트를 캐싱
}
}
// 특정 컨트롤러에만 CORS 적용하고 싶을때.
@Controller
@CrossOrigin(origins = "*", methods = RequestMethod.GET)
public class customController {
// 특정 메소드에만 CORS 적용 가능
@GetMapping("/url")
@CrossOrigin(origins = "*", methods = RequestMethod.GET)
@ResponseBody
public List<Object> findAll(){
return service.getAll();
}
}
AWS (S3 호스팅)
[
{
"AllowedHeaders": [
"Authorization"
],
"AllowedMethods": [
"GET",
"HEAD"
],
"AllowedOrigins": [
"http://www.example.com"
],
"ExposeHeaders": [
"Access-Control-Allow-Origin"
]
}
]