junglast
Published on

HTTP Ajax 요청시 사용하는 withCredentials 옵션의 의미

비동기 HTTP 요청을 보내기 위해 XMLHttpRequest, fetch API, 혹은 axios 등의 HTTP 클라이언트를 사용할 때 아래와 같이 withCredentials 옵션을 지정할 수 있습니다.

/* axios */
axios.get("https://example.com/items", {
  withCredentials: false, // default
})

/* fetch API */
fetch("https://example.com:1234/users", {
  credentials: "include",
})

(fetch API에서는 옵션명이 withCredentials가 아닌 credential입니다.)

이 옵션은 CORS나 Third-party 쿠키 정책등의 다른 개념들과 혼용되어 쓰이는 경우가 대부분이기에 다시 한 번 정리할 필요가 있다고 느껴졌습니다.

의미

withCredentials 옵션은 단어의 의미에서 알 수 있듯이, 서로 다른 도메인(크로스 도메인)에 요청을 보낼 때 요청에 credential 정보를 담아서 보낼 지를 결정하는 항목입니다.

여기서, credential 정보가 포함되어 있는 요청은 아래 두 가지 경우를 의미합니다.

  1. 쿠키를 첨부해서 보내는 요청
  2. 헤더에 Authorization 항목이 있는 요청

따라서, 보내고자 하는 요청이 위 두 가지 항목 중 한 가지라도 포함하고 있다면 withCredentials 옵션을 true로 설정해야만 합니다.

서버에서의 응답

한편, credential 정보가 포함되어 있는 요청이 정상적으로 처리되기 위해서는 해당 요청을 받는 서버 측에서도 다음과 같은 설정이 필요합니다.

  1. 응답 헤더의 Access-Control-Allow-Credentials 항목을 true로 설정해야 합니다.
  2. 응답 헤더의 Access-Control-Allow-Origin의 값이 반드시 설정되어야 합니다. 단 와일드카드 문자("*")는 사용할 수 없습니다.
  3. 응답 헤더의 Access-Control-Allow-Methods의 값을 지정해야 할 경우 와일드카드 문자("*")는 사용할 수 없습니다.
  4. 응답 헤더의 Access-Control-Allow-Headers의 값을 지정해야 할 경우 와일드카드 문자("*")는 사용할 수 없습니다.

유의해야 할 점은 Access-Control-Allow-* 헤더 값들을 지정해야 하는 경우에는, 와일드카드 문자를 제외한 값으로 설정되어야 한다는 것입니다.

이 값이 와일드카드 문자로 설정될 경우, 요청에 대한 응답이 클라이언트로 전해지기는 하지만 클라이언트 js에서는 이 응답에 접근을 할 수 없는 상태가 됩니다. 브라우저가 이를 차단하고 있기 때문입니다. 이는 브라우저 개발자도구에서 자주 볼 수 있는 CORS Error가 표시되는 이유 중 한 가지이기도 합니다.

하지만, preflight가 필요 없는 요청의 경우(대표적으로 GET 요청) Access-Control-Allow-MethodsAccess-Control-Allow-Headers 헤더는 아예 존재하지 않아도 됩니다.

preflight 요청에서의 예외

단, 예외적으로 실제 요청 바로 전에 발생하는 preflight 요청credential 정보를 포함할 수 없습니다. 하지만, 이 preflight 요청에 대한 응답을 보낼 때는 Access-Control-Allow-Credentials 헤더 값이 true로 설정되어야 합니다.


References