쿠키, 세션 스토리지, 로컬 스토리지
정의
쿠키, 세션 스토리지, 로컬 스토리지 모두 브라우저에서 관리하고 사용하는 key-value 저장소이다.
비슷하면서도 몇가지 차이점이 존재한다.
- 데이터를 담을수 있는 용량
- 사용기한 (expiry)
- 서버/클라이언트 사이드 접근성
- HTTP 요청 포함 여부
애초에 브라우저에 저장소가 왜 필요할까요? 보통 데이터는 서버에서 관리가 되는데 말이죠. 이 저장소들은 보통 사용자와 관련된 정보를 담고 있습니다.
- 사용자의 간단한 설정여부 (다크/라이트 모드, 광고성 팝업 오늘 하루동안 보지 않기 등…)
- 사용자의 인증 여부
- 로그아웃 사용자의 장바구니 목록
그 외에 다양하게 존재 할 수 있는데요 여기서 공통점은 보통 사용자의 관한 것들을 기억하는 용도인데요. 그 이유는 클라이언트와 서버가 통신에 사용하는 HTTP는 stateless 한 성질을 가지기 때문입니다. 따라서 사용자가 요청을 보낼때마다 요청을 보낸 사용자를 특정 짓는 방법이 서버측에서는 따로 존재하지 않기 때문에 오늘날 쿠키, 로컬/세션 스토리지에 사용자의 로그인 인증정보를 담고 이것을 요청에 포함시켜 사용자를 인증하고 구분짓는 방식이 자리 잡았습니다.
또한 이런 데이터들은 지워지거나 잃어버려도 큰 부담이 없다는거고 서버가 아닌 클라이언트 (브라우저) 단에서 관리하는게 더 효율적이고 쉽다는 특징도 있습니다.
이번 글에서는 다른 것 보다도 사용자의 로그인 인증과 관련하여 좀 더 살펴보겠습니다.
로컬, 세션 스토리지
로컬과 세션 스토리지는 매우 비슷한데 한가지 명확한 차이점은 로컬 스토리지는 사용자 또는 클라언트 사이드 어플리케이션이 지우지 않는 이상 따로 삭제되거나 만료되지 않는다는 점이 있습니다. 반면 세션 스토리지는 현재 열여있는 창에 (더 정확히는 탭에) 한하여 데이터가 유지되고 그 탭이 닫기면 해당 세션에서 저장했던 데이터는 삭제합니다.
둘의 공통점은 클라이언트쪽에서 데이터 접근이 가능하고 따로 작업을 해주지 않는 이상 자동으로 서버에 요청을 보낼때 포함시키지 않는다는 점입니다.
쿠키
쿠키는 로컬/세션 스토리지와 비슷하게 key-value 데이터를 저장하는데 이때 추가적으로 여러 세팅값을 지정해 줄 수 있습니다.
- Domain - 쿠키를 포함시켜 요청을 보낼 도메인
- Path - 쿠키를 포함시켜 요청을 보낼 도메인의 경로
- Expires/Max-Age - 만료기한
- HttpsOnly - 클라이언트 사이드 접근 허용 여부
- Secure - HTTPS 에서만 송신 여부
- SameSite - 도메인이 다른 곳에서 사용 여부
눈치채셨을지 모르겠지만 위 세팅값으로 인해 쿠키가 로컬/세션 스토리지보다 압도적으로 보안적인 측면이 뛰어납니다. 그리고 사용자의 로그인 인증에 대한 정보를 다룰때는 높은 보안성을 보장해줄 수 있는 쿠키가 더 인기있는 선택지가 됩낟.
사용자 인증
오늘날 사용자 인증은 보통 세션 또는 토큰 방식으로 이루워지는데 두 방법 모두 서버쪽에서 생성한 문자열 값을 클라이언트쪽으로 전달합니다.
세션과 토큰 방식에 대한 설명은 그것 자체로도 많은 설명이 추가될 수 있습니다. 간략하게 세션은 서버에서 해당 사용자에 대해 고유 세션 아이디를 발급을 하고 그 정보를 저장합니다. 그래서 사용자는 발급된 세션 아이디를 쿠키에 보관하고 매 요청시에 포함시키면 서버측은 저장해둔 세션 아이디와 비교를해서 인증 여부를 판단합니다.
토큰 방식도 서버쪽에서 사용자에게 인증에 사용될 토큰 문자열을 발급을 하지만 따로 저장하지는 않습니다. 발급된 토큰을 쿠키에 보관하고 매 요청시에 포함시키면 서버측은 해당 토큰안에 들어있는 정보로 인증 여부를 판단합니다. 토큰안에는 서버의 디지털 서명이 있어서 토큰의 진위여부 판단이 가능합니다.
보안
위에서 언급했듯이 로컬/세션 스토리지는 클라이언트 사이드에서 조작이 용이합니다. 반면 쿠키는 클라이언트 사이드에서 쿠키에 접근이 불가능하도록 HttpOnly 설정을 해줄 수 있습니다. 이 부분은 cross-site scripting 공격에 대응할 수 있어 매우 중요한 이점이 됩니다.
추가로 CSRF (cross site request forgery) 와 같은 공격도 domain, path, SameSite 옵션을 통해 방어 할 수 있습니다.
마무리
간략하게 쿠키, 로컬, 세션 스토리지에 대해 적어보았는데요. 결론적으로는 공부하며 느낀점은 로그인과 유저 인증에 관한 정보는 왠만하면 쿠키를 통해 관리하는게 좋은 practice 인것같습니다. 만약에 어떤 이유로 인해 로컬/세션 스토리지를 사용해야 한다면 추가적으로 데이터를 암호화하는 수고를 거쳐야 하지 않을까 싶어요.
그리고 로컬/세션 스토리지가 그렇다고 쓸모가 없다는 결론도 절대 아닙니다. 쿠키는 용량도 훨씬 적고 요청시에 포함이되서 어느정도의 오버헤드가 생깁니다. 즉 정보 보안에 민감하지 않고 굳이 서버단에서 필요하지 않은 정보는 로컬/세션 스토리지에 넣어서 사용하면 편리할 것 같습니다. 즉 아마 클라이언트 사이드 코드에서 접근하고 사용하게 되는 정보 저장용도로 사용하기 적합할 것같습니다.