[Front-End] 배포 환경에서 쿠키가 저장 안되는 이슈 해결

하영·2022년 11월 2일
12

Front-End

목록 보기
2/4
post-thumbnail

0. 들어가며

지금 진행중인 프로젝트는 universal-cookie로 토큰 관리를 합니다. 로그인 하면 쿠키에 토큰을 저장하는 방식.... 임시 배포를 진행하고 기획자님께 동작 테스트를 요청했는데 로그인이 계속 풀리는 오류를 전해들었습니다 ,,, 잉 ?!? 분명히 로컬 개발 환경에서는 동작했는데 잉잉..... 🥲


어이가 없음 ㅋㅋㅋ ✨ 반짝 ✨

1. 원인을 찾자

_app.tsx가 최초 로드 되었을 때 로그인 여부를 쿠키에 저장된 토큰으로 체크하게 되어있습니다.

  • 쿠키 값이 있다면 로그인 상태. 유저 정보 로드
  • 쿠키 값이 없다면 로그아웃 상태로 localStorage에 저장되어있는 유저 정보를 삭제
  1. 로그인 시도
  2. 서버에서 유저정보를 받아와서 localStorage 에 저장, 토큰은 쿠키에 저장
  3. 홈 화면으로 이동
  4. 갑자기 localStorage에 저장된 유저정보 증발 ?!?

과 같은 오류였는데,, 아무래도 3에서 4로 넘어가며 오류가 발생 한 듯 하였습니다. 쿠키 값이 없다면 localStorage에 저장되어있는 유저 정보 삭제 로직을 수행하는데, 이 부분이 의심되어 동작 여부를 콘솔로 찍어보았습니다.

아니나 다를까, 실제로 그 로직이 수행되었고, 관리자도구를 보니 2에서 3으로 넘어갈 때 Cookie가 저장되지 않는 것이었습니다 ...

2. 원인을 찾자 2

개발 환경과 배포 환경의 차이를 생각해보았습니다.

  • httphttps의 차이
  • localhost:3000domain.com의 차이 즉, 쿠키 저장 도메인이 다른 것

이 두가지의 의문점을 들고 해결해보고자 했습니다.

일단, 구글에서 찾아낸 쿠키 이슈는

  • 백엔드에서 생성한 쿠키가 프론트로 전달되지 않는다
  • 쿠키 옵션 설정에 따라 다르다 (httpOnly, Secure 등등 )
  • axios에 credential 설정을 하였는가?

인데 ... 쿠키를 프론트엔드에서만 쓰고 읽는 이 프로젝트의 해결책에는 해당되지 않는 것 같았습니다.헉 설마?

한가지 실험을 해봤습니다. 쿠키를 아래와 같이 설정하고 localhost 환경에서 실행해보았습니다.

    const cookies = new Cookies(); // 쿠키 생성

    const expires_time = new Date();
    expires_time.setDate(Date.now() + 1000 * 60 * 60 * 24); // 만료 시간 설정

    const max_age = 31536000;
    cookies.set('access_token', accessToken, {
      path: '/', // 쿠키에 접근할 수 있는 경로
      httpOnly: true, // document.cookie와 같이 자바스크립트에서 쿠키에 접근하는 것을 방지
      expires: expires_time, // 쿠키 만료 시점
      maxAge: max_age, // 쿠키 유효 기간
    })

pathexpires, maxAge 는 쿠키 저장 여부에 영향을 크게 미치지 않으니 패스 했고
httpOnly에 집중 해보았는데, httpOnlytrue일 경우에는 프론트엔드 코드에서도 저장이 되지 않는 것이었습니다....! 그래 맞다 ...

쿠키의 httpOnly 옵션은 document.cookie와 같이 브라우저 자바스크립트 코드로 접근할 수 있는지 없는지에 대한 유무입니다.
httpOnlytrue 라면 서버 코드 즉 백엔드 에서만 접근이 가능합니다.

즉, httpOnlytrue라면 프론트엔드 코드에서 쿠키 저장이 불가합니다.
브라우저도 결국은 자바스크립트 기반으로 동작하니까 .....

2. 해결해보자,, 아차 !

로컬 호스트 환경에서는, 쿠키 저장 도메인이 localhost 입니다.

프론트엔드에서만 쿠키를 저장하고 사용하는 것은 session storagelocal storage 같은 웹 스토리지에 저장하는 것 과 동일한 역할을 한다고 생각합니다.

그렇다. 철저히 쿠키의 용도를 잘못 알고, 제대로 사용하지 못하고 있었던 것 이었습니다.

그러니까... HTTP_ONLY를 혹시 싶어 가시적으로 false 변경하였더니 맙소사 저장되는 것이었습니다.

3. 새로운 리팩토링 방향

제가 쿠키에 저장된 토큰을 백엔드에 전달하는 방법은,
페이지가 렌더될 때 쿠키에 저장된 토큰의 여부를 확인하고
토큰이 존재한다면 axios객체의 인증 헤더에 세팅해주는 것 이었습니다.

쿠키 저장 이슈가 발생하기 전까지는 위의 방식으로 토큰을 저장하고 전달하는 방법이 정석일 것이라고 생각하고 도입했었습니다.

하지만, 쿠키가 저장되지 않는 이슈가 발생했고 여러 서치를 해보니 쿠키 저장 정석 방법이 있다는 것을 찾아내었습니다.

http_onlysecure 같은 보안 옵션을 모두 활성화 해 주는 것이 좋다고 합니다. 그러기 위해서는,

  • 백엔드가 응답 헤더에 set-cookie : access_token 을 삽입하게 되면 프론트엔드가 응답 받았을 시 저장 조건에 해당한다면 쿠키를 자동으로 저장한다.
  • https 에서만 쿠키를 저장할 수 있게 한다.
  • 프론트엔드와 백엔드의 도메인이 동일 할 때만 쿠키가 저장될 수 있게 한다.

하지만, 개발 환경에서 프론트 엔드와 백엔드의 도메인이 동일하기란 쉽지 않습니다. 대부분 로컬 환경에서 개발하니까요. 그러기에 프론트엔드와 백엔드의 도메인을 동일하게 하려면 편법이 필요하다고 합니다.

프로젝트 리팩토링 기간을 갖으면서, 토큰 전달 방식을 위와 같이 변경 할 예정입니다.

4. 마치며

이번 이슈는 쿠키 저장 옵션을 잘못 봐서 발생한, 찾기는 어렵지만 해결은 정말 쉬운 삽질이었습니다. 하지만 이를 통해 새로운 쿠키 저장 방식을 공부하였으니 저는 이 또한 가치 높은 시간 이었다고 생각합니다 🥰

삽질은 허탈한 것이 아닌 같은 실수를 반복하지 않고 지식을 깊게 얻을 수 있는 좋은 기회라고 생각합니다 😊

공부하며 작성한 글이기 때문에 부족한 부분이나 궁금한 점이 있으시다면 댓글 자유롭게 남겨주세요 😊 감사합니다!

profile
maker를 넘어 solver를 지향합니다.

2개의 댓글

comment-user-thumbnail
2022년 12월 5일

안녕하세요 :) 저도 같은문제로 구글링하다 좋은글을 읽게되었습니다 혹시 어떻게 리팩토링 하셨는지 알려주실수 있으실까요??

1개의 답글