토큰 저장은 어디에? 쿠키 vs 세션 vs 웹 스토리지 간단 비교
나는 왜 토큰을 localStorge에 저장하는 방식만 생각했나 ?
혼자서 firebase를 이용한 로그인을 구현할 때에는 로컬 스토리지에 정보를 저장했다.( 토큰 비슷하게 로그인 유무와 닉네임만 파악할 수 있게)
그리고 이번 백엔드와 협업하면서 자연스럽게 토큰을 로컬 스토리지에 저장을 했다. 그리고 다른 프론트엔드와 얘기하는 도중 대부분의 사람들이 쿠키에 저장을 한 것을 보고 이유를 물었는데, 대부분이 그냥 쿠키로 하는 코드를 봤다는 대답에 궁금해서 알아보고 정리해보고자 이 글을 쓰려한다.
세션 스토리지 vs 로컬 스토리지 vs 쿠기 vs 세션
웹 스토리지
- 클라이언트에 데이터를 저장할 수 있도록 HTML5부터 추가된 저장소이다.
- 데이터 형테는 Key-value 스토리지 형태로 구성된다.
- 오직 문자형 데이터 타입만 저장이 가능하다. 다만 객체 등 문자열로 변경할 수 있기 때문에 아직까지 나는 이 부분에서 큰 불편함을 느끼진 못했다.
- 조작할 때는 JS 내에서만 수행할 수 있다.
vs 쿠키
- 매번 전송되지 않기 때문에 자동 전송의 위험성이 없다.
- 저장 용량이 비교적 크다
- 도메인, 프로토콜, 포트 단위로 접근하기 때문에 CSRF로부터 안전하다.
- 로컬 스토리지
- 사용자나 JS로직에서 지우지 않는 이상, 브라우저를 종료해도 계속 브라우저에 남아있다. (단, 동일한 브라우저 환경에서만 해당된다)
- 보통 자동 로그인 등에 사용한다
- 세션 스토리지
- 윈도우, 브라우저 탭을 닫을 경우 사라진다.
- 보통 일시적으로 필요한 데이터를 저장할 때 사용한다. (비회원 장바구니, 일회성 로그인 정보, 입력폼 등)
쿠키, 세션
- 쿠키
- 클라이언트에 저장되는 키와 같이 들어있는 작은 파일이다.
- 상태 정보를 로컬에 저장했다 참조한다.
- Response Header에 Set-Cookie 속성을 사용하면 클라이언트에서 쿠키를 만들 수 있다.
- 사용자가 따로 요청하지 않아도 모든 Request(서버 요청) 시에 자동으로 Header에 넣어져 전송된다.
- 세션
- 브라우저에 저장하는 방식이 아닌 세션은 서버에서 관리한다.
- 클라이언트를 구분하기 위한 ID값을 부여하고 서버에 접속해서 브라우저를 종료할 때까지 인증 상태를 유지한다.
- 접속 제한을 두어 일정 시간 응답이 없으면 정보가 유지되지 않은 기능을 수행할 수도 있다.
- 서버에 두기 때문에 보안에 좋다.
준 결론
각 저장소는 그에 맞는 기능과 역할이 있는 듯하다.
토큰을 저장하는데 정해져 있는 공식은 없는 것 같다. 상황에 맞게 작성하면 될 것 같은 생각이 들고 그 선택을 한 이유에 대한 자신만 있으면 될 것 같다.
우선 위 특징을 알아보면서 큰 단점을 얘기하지 않았다.
모든 내용을 다루기에는 아직 수준 미달에 방대해 토큰을 기준으로 쿠키와 로컬 스토리지만 알아보려고 한다.
우선 로컬 스토리지는 앞서 말했듯 하나의 도메인에 제한되어 있지 않은 큰 장점과, CSRF 해킹에 위험성에서 벗어날 수 있다. 다만 XSS 해킹 공격에는 취약하여 토큰을 탈취 될 수 있다는 큰 단점도 존재한다.
쿠키는 반대로 한정된 도메인에서만 사용이 된다는 단점과, XSS 해킹 공격에는 해방되지만 CSRF 공격의 위험성이 생긴다는 단점이 있다.
이렇게 상반되는 장 단점이 있는데 쿠키는 해당 단점을 보완할 수 있다고 한다.
토큰이 필요해질 때 현재 쿠키에 있는 토큰을 사용해 새로운 토큰을 받아올 수 있는 API를 구현하여 도메인에 문제를 해결하고, CSRF 토큰의 사용, HTTP 요청 레퍼러 체크 등 해결할 수 있는 방법이 있다.
결론
- 각 저장소에 역할에 맞는 기능을 수행하자.
- 특정한 이유가 없다면 쿠키에 저장하는 것이 바람직해 보인다.