CORS란?
- CORS(Cross-Origin Resource Sharing)는 출처가 다른 자원을 공유한다는 뜻으로, 한 출처에 있는 자원에서 다른 출처에 있는 자원에 접근하도록 하는 개념
- 직역하면, 교차되는 출차 자원들의 공유를 뜻함
- 다른 출처에 있는 자원을 요청하면, 이를 교차 출처 요청이라고 부름
교차 출처 리소스 공유(CORS)는 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제.
웹 애플리케이션은 리소스가 자신의 출처(도메인, 프로토콜, 포트)와 다를 때 교차 출처 HTTP 요청을 실행
출처란?
위의 구성요소 중에서 Protocol + Host + Port 이 세 가지가 같으면 동일 출처(Origin)라고 합니다.
다른 출처 요청일 경우, CORS 정책에 준수하여 요청해야만 정상적으로 응답을 받을 수 있다.
다른 출처 요청의 위험성
<img>, <script>, <frame>, <video>, <audio> 등이 웹에 등장하면서, 페이지 로딩 이후 브라우저에서 이러한 하위 자원들을 가져올 수 있게 되어 동일 출처, 다른 출처 모두 호출이 가능하게 되었다.
예를 들어 CORS 정책이 없이 모든 다른 출처 요청이 가능한 브라우저가 있다고 해보자
홈페이지를 서핑하고 있는데, <script>가 심어진 evil.com 페이지를 열었다고 생각해보자. 굉장히 유용한 정보를 담고있는 사이트이지만, 페이지를 열면서 <script>가 실행되어 'Delete /account'를 요청하도록 되어있다. Ajax 호출로 은행 API를 출하여 나의 은행 계좌를 삭제해버리는 사고가 발생한다.
따라서, 다른 출처의 접근을 막기 위해 동일 출처 정책이 등장한 것이다.
동일 출처 정책 (Same-Origin policy)
- 다른 출처로부터 조회된 자원들의 읽기 접근을 막아 다른 출처 공격을 예방
- 그러나, 다른 출처에서 얻은 이미지를 담은 <img>, 외부 주소를 담는 <link> 같은 여러 태그를 허용
- 동일 출처 정책의 정확한 구현 명세는 없지만 최신의 브라우저들은 일정 규칙을 따른다. (RFC6454)
- 동일출처 정책은 다른 출처 자원을 가져오는 것을 굉장히 제한적으로 허용
- SPA와 미더이 중심 웹 사이트들이 더욱 늘어나고 있으므로 관련 규칙들도 계속 늘어남에 따라, 다른 출처 리소스에 접근성을 높이기 위해 CORS가 등장했다
Spring boot에서 cross-origin 설정하기
1. 메서드에서 설정하기
@RestController
@RequestMapping("/account")
public class AccountController {
@CrossOrigin
@RequestMapping(method = RequestMethod.Get, path = "/{id}")
public Account retrieve(@PathVariable Long id) {
...
}
@RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
public void remove(@Pathvatiable Long id) {
...
}
}
retrieve() 메서드에 선언된 @CrossOrigin의 기본 설정은 다음과 같다.
1. 모든 출처 허용
2. 허용된 HTTP 메서드는 @RequestMapping 에 선언된 메서드들이다.
3. 프리플라이트 응답은 30분 동안 캐시상태
2. 컨트롤러에서 설정하기
@CrossOrigin(origins = "http://Example.com", maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {
@RequestMapping(method = RequestMethod.GET, path = "/{id}")
public Account retrieve(@PathVariable Long id) {
...
}
@RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
public void remove(@PathVariable Long id) {
...
}
}
컨트롤러에 설정했으므로 AccountController에 있는 retrieve()와 remove() 함수 모두에 적용된다
3. 개별 적용
@CrossOrigin(maxAge = 3600)
@RestController
@RequestMapping("/account")
public calss AccountController {
@CrossOrigin("http://example.com")
@RequestMapping(method = RequestMethod.GET, "/{id}")
public Account retrieve(@PathVariable Long id) {
...
}
@RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
public void remove(@PathVariable Long id) {
...
}
}
스프링에서 여러가지 CORS 정책을 복합해서 설정 할 수 있음
모든 메서드들은 3600초가 캐시 시간. retrieve() 메서드는 허용출처가 "http://example.com" 밖에 안된다.
하지만, remove() 메서드는 별도의 설정이 없어 모든 출처가 가능.
4. 전역 설정
CORS 정책의 설정은 WebMvcConfigurer를 구현하여 설정이 가능하다.
이는 필터를 기반으로 하여, 전역적으로 모든 요청에 대해서 검사를 하기 때문이다.
@Configuration
@EnableWebMvc
public calss WebConfig implements WebConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
참고
'ssung_항해일지 > CS 지식 및 기술면접' 카테고리의 다른 글
DI (Dependency Injection) (0) | 2023.05.09 |
---|---|
REST API (0) | 2023.05.08 |
객체지향 프로그래밍(OOP) (0) | 2023.05.08 |
시간 복잡도(Time Complexity) 와 공간 복잡도 (Space Complexity) (1) | 2023.04.25 |
배열과 링크드리스트 (0) | 2023.04.25 |