이번 주에는 http 모듈을 불러와 서버를 구현하고, 이를 express를 이용하여 리팩토링하는 시간을 가졌다. 이 과정에서 만난 CORS가 무엇인지, 실제 프로젝트에서 어떻게 다루면 좋은지 작성해 보고자 한다.
CORS(Cross-Origin Resource Sharing, 교차 출처 리소스 공유)는 웹 애플리케이션이 다른 출처의 리소스에 접근해야 할 때, 애플리케이션이 접근 권한을 부여받도록 브라우저에게 알려주는 체제이다.
SOP(Same-Origin Policy, 동일 출처 정책
같은 출처(Origin: 프로토콜, 호스트, 포트의 조합)의 리소스만 공유가 가능하다는 정책이다. '같은 출처'이므로 프로토콜이나 호스트, 포트 중 어느 하나라도 다르다면 SOP를 위반하는 것이다. 이 정책은 다른 사이트와의 리소스 공유를 제한하여 중요한 정보가 타 사이트의 코드에 의해 새어나가는 것을 방지한다. 이러한 보안상의 이점 때문에 모든 브라우저는 기본적으로 SOP 정책을 사용한다.
CORS는 크게 세 가지 방식으로 동작한다.
글자 그대로 실제로 요청을 보내기 전에 사전 요청(Preflight Request)을 보내보는 것이다. 이 요청은 OPTIONS 메서드로 보내지며 해당 출처 리소스에 접근 권한이 있는지 확인하는 역할을 한다.
// 실제 요청 시 어떤 메서드와 헤더가 사용될 것인지 미리 서버에게 알려준다
'Access-Control-Request-Method': 'POST',
'Access-Control-Request-Headers': 'Content-Type'
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Accept',
'Access-Control-Max-Age': 10
특정 조건이 만족되면 프리플라이트 요청을 생략하고 요청을 보내는 것이다.
다른 출처 사이의 통신에서 보안을 강화하고 싶을 때 사용하는 방법으로, 헤더에 인증 정보를 담아 요청을 보낸다.
1. fetch API의 경우
fetch("https://example.com:1000/projects", {
credentials: "include",
});
2. axios의 경우
axios.get("https://example.com/items", {
withCredentials: true,
});
Access-Control-Allow-Credentials : true
를 넣어준다.Access-Control-Allow-Origin
을 정확하게 설정한다. 즉, 와일드카드(*)를 사용하지 않는다.Access-Control-Allow-Methods
와 Access-Control-Allow-Headers
의 값을 지정해야 할 경우 와일드카드(*)를 사용하지 않는다.