1. 정의
CORS(Cross-Origin Resuorce Sharing) 교차 출처 자원 공유
웹 페이지 상의 제한된 자원을 최초 자원이 서비스된 도메인 밖의 다른 도메인으로부터 요청할 수 있게 허용하는 구조.
웹 페이지는 교차 출처 이미지, 스타일시트, 스크립트, iframe, 동영상을 자유롭게 임베드할 수 있다.
단, 특정 교차 도메인 간 요청, 특히 Ajax요청은 SOP(동일-출처 보안 정책)에 의해 기본적으로 금지된다.
👉🏻 추가 HTTP헤더를 사용하여 다른 출처의 자원을 공유할 수 있도록 권한을 부여하는 것으로 SOP를 우회하기 위한 방법 중 가장 권장되는 방법
SOP(Same-Origin Policy) 동일 출처 정책
동일 출처에서만 자원을 공유할 수 있게 제한하는 보안 정책
동일 출처(Same Origin)
Origin의 구성인 sceme(protocol), host, port가 모두 같을 때를 말함
Origin의 구성
http:// | www.example.com | :80 |
Scheme(Protocol) | HostName(domain) | Port |
2. CORS 동작
1) 프리플라이트 요청(Preflight Request)
2) 단순 요청(Simple Request)
3) 인증 정보 포함 요청(Credentialed Request)
3. Spring Boot에서 CORS 설정
1) @CrossOrigin 애너테이션을 각 Controller에 설정하기
👉🏻 장점: 컨트롤러마다 세부 설정이 가능 / 단점: 컨트롤러가 많아짐, 설정 내용이 같다면 비효율적
@RestController
@RequestMapping("/path")
@CrossOrigin(origins = "*", allowedHeaders = "*") // 허용할 origins이나 methods 지정(origins, methods, maxAge, allowedHeaders 사용)
public class ExampleController {
}
// 세션 정보(쿠키)를 같이 넘기려면 withCredentials 활성화 필요(js에서도 옵션 설정해야함)
// allow origin = "*"와 함께 사용 안됨, {"aaa.com","bbb.com"}과 같이 특정해야 함
@CrossOrigin(origins = "aaa.com", withCredentials = "true")
메소드에도 @CrossOrigin 적용 가능
@RestController
@RequestMapping("/path")
public class ExampleController {
@CrossOrigin(origins="*") // 메소드에도 적용 가능
@RequestMapping(value = "/{value}",method = RequestMethod.DELETE)
public ResponseEntity<String> delete(@PathVariable Long reservationNo) throws Exception{
}
}
2) @Configuration으로 통합 설정(전역 설정)
WebConfig 클래스 생성 -> WebMvcConfigurer를 implements -> addCorsMappings 메소드 오버라이드(재정의)
@Configuration // 설정 파일이라는 것을 알려주는 애너테이션
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) { // addCorsMappings 메소드 오버라이드
registry.addMapping("/api/**"); // CORS를 적용할 URL패턴(API) 정의
.allowedOrigins("http://locaolhost3000"); // 자원 공유 허용할 Origin 지정(생략 시 *와 같은 의미로 전체 허용)
.allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD", "OPTIONS"); // 허용할 HTTP method 지정
.allowedHeaders("header1", "header2", "header3") // 요청 허용할 헤더 목록
.exposedHeaders("header1", "header2"); // 단순 헤더 이외의 응답 헤더 목록
.allowCredintials(true) // 쿠키와 같은 자격 증명 요청 허용 여부
.maxAge(3000); // maxAge메소드를 이용해서 원하는 시간만큼 pre-flight 리퀘스트를 캐싱
}
addMapping | CORS 적용할 URL 패턴 정의로 "/**"는 모든 경로 |
allowedOrigins | 자원 공유 허용 할 Origins(출처) 설정으로 "*"은 모든 Origin(출처) 허용 .allowedOrigins("http://localhost:8080", "http://localhost:8081"); // 한꺼번에 여러 Origin 설정 가능 |
allowedMethods | 허용 할 HTTP 메소드 설정으로 "*"로 모든 메소드 허용 여러 http 메소드 지정 가능: GET, POST, PUT, DELETE, OPTIONS, PATCH |
allowedHeaders | 요청 허용 할 헤더 목록 |
exposedHeaders | 단순 헤더 이외의 응답 헤더 목록 |
allowCredintials | 쿠키와 같은 자격 증명 요청 허용 여부(true or false), allowedOrigins("*")설정 시 사용 불가(에러 발생) 👉🏻 다른 도메인 서버에 인증하는 경우에만 사용, true 설정 시 보안상 이슈 발생 가능성 있음 |
maxAge | 프리플라이트 요청 응답을 클라이언트가 캐시할 수 있는 시간(초) 구성 |
📄 레퍼런스
https://docs.aws.amazon.com/ko_kr/apigateway/latest/developerguide/how-to-cors.html
https://evan-moon.github.io/2020/05/21/about-cors/
https://dev-pengun.tistory.com/entry/Spring-Boot-CORS-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0
https://goodteacher.tistory.com/397
https://sowells.tistory.com/170
'Spring > Springboot' 카테고리의 다른 글
Controller, Service, Repository의 역할 (0) | 2022.11.08 |
---|---|
Controller와 HTTP Request 메시지 (0) | 2022.11.08 |
빌드 관리 도구 Maven과 Gradle 비교 (0) | 2022.11.08 |
AOP(Aspect-Oriented Programming) 관점 지향 프로그래밍 구현 (1) | 2022.11.08 |
HTTP 메시지 이해 (0) | 2022.09.05 |