쿠키, 세션, 로컬 스토리지




1. 쿠키, 세션, 로컬스토리지 왜 사용해?

http 프로토콜은 connectionless, stateless한 특성이 있기 때문에

  • 클라이언트의 요청-응답이 이루어지면 연결이 끊김
  • 연결이 끊기는 순간 클라이언트-서버의 통신이 끝나며, 상태정보는 유지하지 않음
  • 하지만 통신을 했다는 기억을 가지고 싶다면?



2. 쿠키

  • 클라이언트 로컬에 저장되는 키와 값이 들어있는 데이터 파일
  • 사용자 인증이 유효한 시간을 명시할 수 있고, 유효시간이 유효하다면 브라우저가 종료되어도 인증이 유지된다.
  • 사용자가 따로 요청하지 않아도, 브라우저가 request header에 넣어서 자동으로 넣어서 서버에 전송(서버에 자동 전송)
  • 사용자가 직접 쿠키를 만들수도 있고, 브라우저에서 만들어서 줄 수 도 있다.
  • 암호화가 존재하지 않는다. (jwt 사용)

쿠키의 동작 방식

쿠키

  • 클라이언트가 페이지를 요청
  • 서버에서 쿠키 생성
  • http header에 쿠키를 포함시켜 응답
  • 클라이언트가 같은 요청을 할 경우 http 헤더에 쿠키를 함께 보냄
  • 서버에서 쿠키를 읽어 변경이 필요한 경우 쿠키를 업데이트하여 변경된 쿠키를 http 헤더에 포함시켜 응답

하지만 쿠키는 4kb의 용량 제한이 있다. 이를 넘어선다면?
html5부터 추가된 로컬 스토리지와 세션 스토리지를 사용해야 한다.



3. 로컬 스토리지

  • 사용자가 직접적으로 지우지 않는 한 데이터가 영구적이다.
  • ex) 자동 로그인



4. 세션

  • 데이터가 영구적이지 않다. (윈도우, 탭 닫을 시 제거)
  • 일회성 로그인
  • 쿠키를 기반으로 하지만, 사용자 정보 파일을 브라우저가 아닌 서버 측에서 관리한다.
  • 사용자에 대한 정보를 서버에 두기 때문에 쿠키보다 보안에 좋지만, 서버 메모리를 많이 차지하게 된다.
  • (동시 접속자의 수가 많으면, 서버 과부하로 성능 저하의 요인)
  • 클라이언트가 request를 보내면, 서버에서 해당 클라이언트에게 유일한 Id를 부여


세션의 동작 방식

  • 클라이언트가 서버에 접속 시 세션 id를 발급
  • 클라이언트는 세션 id에 대해 쿠키를 사용해서 저장하여 가지고 있다.
  • 클라이언트는 서버에 요청시 이 쿠키의 세션 id를 서버에 전달
  • 서버는 세션 id를 전달받아 별다른 작업 없이 세션 id로 세션에 있는 클라이언트 정보를 가져온다.
  • 클라이언트 정보를 가지고 서버 요청을 처리한뒤 클라이언트에게 응답



5. 뭅스터에 적용하기

내가 생각했을 때, 로컬 스토리지, 쿠키, 세션의 단점은 다음과 같다.


로컬 스토리지의 단점

  • 만료 기한이 없다.
  • 보안 위험이 크다. (httpOnly, secure 등의 설정 불가)
  • server에 요청시 header에 직접 실어보내야 한다.


쿠키 단점

  • 로컬 스토리지보다는 낫지만 보안에 취약하다.


세션 단점

  • 보안에는 좋지만, 토큰을 db에 저장하므로 시간이 오래걸리며, db 부하가 생긴다.


그래서 세가지의 단점을 최대한 보안하고, 장점을 극대화하기 위해
쿠키+세션+응용으로 구현하고자 한다.

How?

  • 쿠키를 사용하여 토큰을 쿠키의 저장
  • 이 때 생기는 보안의 문제를 jwt를 사용하여 해결(accessToken, refreshToken)
  • 세션 대신 redis server에 토큰을 저장
  • redis는 인메모리이기 때문에 db에 접근하는 시간을 줄여준다.