저번 포스팅에서는 간단한 배경과 SOP 등에 대해 알아보았다. 기본적인 흐름은 간단하지만, CORS가 동작하는 방식은 한 가지가 아니라 세 가지의 시나리오에 따라 변경된다. 이번엔 CORS의 동작방식에 집중하고, 오류 발생시 어떻게 해결하거나 예방할 수 있을지 알아보겠다.
브라우저는 요청을 한번에 보내지 않고 예비 요청과 본 요청으로 나누어서 서버로 전송한다. 이때 브라우저가 본 요청을 보내기 전에 보내는 예비 요청을 Preflight라고 부르는 것이며, 이 예비 요청에는 HTTP 메서드 중 OPTIONS
메서드가 사용된다.
Access-Control-Request-Method
)Access-Control-Request-Headers
)Origin
) 총 3가지의 HTTP request headers를 사용하는 HTTPMethod(OPTIONS
) 요청이다.
Access-Control-Request-Method
Access-Control-Request-Headers
본 요청을 보내기 전에 브라우저 스스로 이 요청을 보내는 것이 안전한지 확인하는 것.
fetch API
를 사용하여 브라우저에게 리소스를 받아오라는 명령을 내린다.일반적으로 브라우저에서 자동으로 발생된다. 그래서 요청을 직접 작성할 필요가 없고, 필요한 경우에만 나타나므로 단순한 요청(Simple Requests)의 경우에는 사전 요청이 생략된다.
예비 요청을 보내지 않고 바로 서버에게 본 요청을 보낸 후, 서버가 이에 대한 응답의 헤더에
Acces-Control-Allow-Origin
등과 같은 값을 보내주면 그때 브라우저가 CORS 정책 위반 여부를 검사하는 방식.
특정 조건을 만족하는 경우에만 예비 요청을 생략할 수 있다.
GET
, HEAD
, POST
중 하나의 메서드User-Agent
가 자동으로 설정한 헤더 외. Content-Type
헤더 중 다음의 값자격 증명을 포함한 요청. 다른 출처간 통신에서 보안을 강화하고 싶을 때 사용하는 방법.
기본적으로 브라우저가 제공하는 비동기 리소스 요청 API인 XMLHttpRequest
객체나 fetch
API는 별도의 옵션 없이 브라우저의 쿠키 정보나 인증과 관련된 헤더를 함부로 요청에 담지 않는다. 이때 요청에 인증과 관련된 정보를 담을 수 있게 해주는 옵션이 바로 credentials
옵션이다. HTTP Cookies와 HTTP Authentication 정보를 인식한다.
Access-Control-Allow-Credentials
헤더를 true
로 설정하여 클라이언트가 인증 정보를 포함한 요청을 허용해야 한다.credentials
옵션을 include
로 설정하여 브라우저에게 인증 정보를 포함시킬 것을 명시해야한다. Access-Control-Allow-Origin
에 *
는 사용할 수 없으며 명시적인 URL이어야 한다.fetch('https://api.example.com/data', {
method: 'GET',
credentials: 'include' // 인증 정보를 포함하기 위해 credentials 옵션을 include로 설정
})
.then(response => {
// 응답 처리
})
.catch(error => {
// 오류 처리
});
fetch('https://api.example.com/data', {
method: 'GET',
headers: {
'Origin': 'https://www.example.com', // 요청을 보내는 출처
'Access-Control-Request-Method': 'GET', // 요청하는 HTTP 메서드
'Access-Control-Request-Headers': 'Authorization, Content-Type' // 요청하는 헤더들
},
mode: 'cors' // CORS 모드로 요청 보내기
})
.then(response => {
// 응답 처리
})
.catch(error => {
// 오류 처리
});
Origin
: 요청을 보내는 출처. 클라이언트는 이 헤더를 설정하여 자신의 출처를 서버에 알림.Access-Control-Request-Method
: 요청하는 HTTP 메서드를 나타낸다. 클라이언트가 실제 요청을 보내기 전에 이 헤더를 사용하여 서버에게 허용되는 메서드를 물어봄.Access-Control-Request-Headers
: 요청하는 헤더들을 나타낸다. 클라이언트가 특정 헤더들을 실제 요청에 포함시키기 전에 이 헤더를 사용하여 서버에게 허용되는 헤더들을 물어봄.Access-Control-Allow-Origin
세팅하기Access-Control-Allow-Origin
헤더에 정석대로 서버에서서 알맞은 값을 세팅해주는 것. *
를 사용하여 세팅한다면 모든 출처에서 오는 요청을 받겠다는 의미로 심각한 이슈가 생길 수 있음.CORS 정책 위반 관련하여 오류를 예방할 수 있는 방법의 경우엔, 아직 스스로 실무에 대한 경험이 없어 공부를 해도 이해를 할 수 없는 영역이라 생략하겠다.