CORS란?
CORS
는 Cross-Origin Resource Sharing 의 약자로 처음 리소스를 제공한 도메인(Origin)이 현재 요청하려는 도메인과 다르더라도 요청을 허락해 주는 웹 보안 방침.- 브라우저는
same-origin policy(동일 출처 정책)
에 의해 cross-origin의 리소스 요청을 차단
Origin이란?
- Protocal, Host, Port를 합친 것
- https: //(=Protocol) localhost(=Host) :3000(=Post)
cross-origin 요청 종류( = origin이 다른경우)
- 다른 도메인 (ex: example.com에서 test.com으로)
- 다른 하위 도메인 (ex: example.com에서 store.example.com으로)
- 다른 포트 (ex: example.com에서 example.com:81로)
- 다른 프로토콜 (ex: https 에서 http으로)
CORS방침으로 요청이 거절되는 과정
- 브라우저에서 페이지를 요청
- 프론트 엔드 서버(localhost:3000)에서 페이지를 받음 (현재 페이지의 Origin)
- 백엔드 서버(localhost:8080)로 HTTP 리퀘스트를 보냄
- 요청의 Origin이 localhost:8080이 아니므로 거절
CORS 거절 해결방법
이러한 거절을 해결하려면 백엔드 쪽에서 CORS 방침 설정을 해주어야한다.
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
private final long MAX_AGE_SECS = 3600;
@Override
public void addCorsMappings(CorsRegistry registry) {
registry
// 모든 경로에 대해
.addMapping("/**")
// Origin이 http://localhost:3000인 경우
.allowedOrigins("http://localhost:3000")
// 아래의 메소드를 이용한 요청을 허용한다.
.allowedMethods("GET","POST","PUT","PATCH","DELETE","OPTIONS")
// 모든 헤더와
.allowedHeaders("*")
// 인증(Credential) 에 관한 정보도 허용한다.
.allowCredentials(true)
// preflight 캐시 저장기간 설정
.maxAge(MAX_AGE_SECS);
}
}
@RestController
public class ApiController {
/*
@CrossOrigin(origins = “허용주소:포트”,maxAge=3600)
모든 origin 허용은 @CrossOrigin(origins="*") 설정
maxAge로 preflight 캐시 저장기간 설정
*/
// http://localhost:8080 에서 들어오는 요청만 CORS 허용
@CrossOrigin(origins = "http://localhost:8080")
@PostMapping("/")
public String postSuccess() {
return "REST API 호출 성공";
}
}
preflight란?
- 브라우저는 cross-origin 요청을 전송하기 전에 OPTIONS 메소드로 사용해 요청을 보낸다.
- Response로 Access-Control-Allow-Origin과 Access-Control-Allow-Methods가 넘어오는데 이는 서버에서 어떤 origin과 어떤 method를 허용하는지 브라우저에게 알려주는 역할을 한다.
- 브라우저는 OPTIONS 요청이 반환되면 CORS 여부 및 요청메소드 사용 가능 여부를 확인하고, cross-origin(원래 보내려던 원요청) 요청을 보낸다.
-> 서버 측에서 그 요청의 메서드와 헤더에 대해 인식하고 있는지를 체크하는 것이 preflight
-> 매번 preflight를 보내지는 않고 캐시 저장 기간을 설정하여 보관할 수 있다.