쿠키, CORS 이슈와의 눈물 나는 씨름..

💛 nalsae·2023년 5월 12일
1

🔥 트러블 슈팅

목록 보기
3/7
post-thumbnail

 이번 글에서는 캘린더 웹 애플리케이션 "피플(Piece-Plan)" 프로젝트에서 JWT를 사용하여 인증과 인가를 구현할 때 마주쳤던 이슈를 소개해보고자 한다.

🔥 문제 상황

 우선 이슈를 소개하기 이전에 상황 설명을 잠깐 하자면, 프로젝트에서 인증과 인가를 구현하기 위해 JWT를 사용하여 쿠키로 주고 받는 로직을 구현한 상태였다. 따라서 서버에서는 응답을 보낼 때 헤더에 동봉할 쿠키가 정상적으로 생성되는 부분까지 console로 확인이 가능했다. 그런데 막상 응답을 보낸 후에 클라이언트 단에서 확인해보면 CORS 에러가 발생하면서 생성한 쿠키를 응답 받은 내용 어떤 곳에서도 찾을 수가 없었다. 아니 분명 서버 로직에서 JWT도 정상적으로 발급되는 것을 확인했고, 쿠키도 console로 확인할 수 있었는데 대체 뭐가 문제란 말인가? 이 부분 때문에 몇 시간 동안 고민하다가 구글링을 했는데 막상 해결 방법은 너무 쉬워서 허탈했다.. ㅎㅎ


🔨 해결 과정

❌ 문제 해결 전 클라이언트 로직

// Login.js
const { data: isSuccess } = await axios.post('/login', { id, password });

⭕ 문제 해결 후 클라이언트 로직

// Login.js
const { data: isSuccess } = await axios.post('/login', { id, password }, { withCredentials: true });

❌ 문제 해결 전 서버 로직

// server.js
res.cookie('accessToken', accessToken, {
    maxAge: 1000 * 60 * 60 * 24 * 7, // 7d
    httpOnly: true,
  });

res.send(true);

⭕ 문제 해결 후 서버 로직

// server.js
res.setHeader('Access-Control-Allow-Credentials', 'true');

res.cookie('accessToken', accessToken, {
  maxAge: 1000 * 60 * 60 * 24 * 7, // 7d
  httpOnly: true,
});

res.send(true);

 클라이언트와 서버 로직 각각 문제 해결 전후의 코드 차이는 아주 간단하다. 바로 credentials 관련 옵션을 요청과 응답을 전송할 때 각각 지정해준 것뿐이다. 클라이언트에서 withCredentials 옵션을 추가하면 HTTP 요청을 전송할 때 인증 정보를 동봉할지 결정할 수 있다. 또한 서버에서 HTTP 응답 헤더에 Access-Control-Allow-Credentials 옵션을 추가하면 역시 인증 관련 옵션을 추가할 수 있다. 정리하면 헤더에 동봉되는 쿠키를 서버, 클라이언트에서 정상적으로 참조하기 위해서는 서버와 클라이언트 각각 credentials 관련 옵션의 값을 true로 설정해야 한다는 것이다.

 프로젝트에서는 다양한 ajax 요청 방법 중 axios 라이브러리를 선택했기 때문에 요청을 보낼 때 withCredentials 옵션을 세 번째 인수로서 객체 안에 설정해주었지만, fetch API나 XMLHttpRequest 등 ajax 요청 방법에 따라 조금씩 상이하다. 이는 다음과 같다.

// fetch API 사용 시
fetch(URL, {
	method: "POST",
	credentials: "include",
})

// XMLHttpRequest 사용 시
const xhr = new XMLHttpRequest();
xhr.open('GET', URL, true);
xhr.withCredentials = true;

🤔 느낀 점

 이전부터 CORS에 대해 계속 들어만 보았지, 실제로 프로젝트를 하면서 이번 글에서 다루는 쿠키 덕분에 처음으로 CORS 에러를 경험할 수 있었다. 몇 시간 동안 머리를 싸매고 console도 찍어보고 로직도 수정하면서 머리를 싸맸는데, 막상 구글링을 해보니 생각보다 너무 간단한 문제여서 허탈했다. 아무래도 CORS를 경험해보지 않았던 상태였기 때문에 CORS 관련 문제일 것이라고 상상조차 못했는데, 앞으로는 CORS 에러라고 쉽게 짐작할 수 있으리라.. ㅎㅎ

profile
𝙸'𝚖 𝚊 𝚍𝚎𝚟𝚎𝚕𝚘𝚙𝚎𝚛 𝚝𝚛𝚢𝚒𝚗𝚐 𝚝𝚘 𝚜𝚝𝚞𝚍𝚢 𝚊𝚕𝚠𝚊𝚢𝚜. 🤔

0개의 댓글