프로그래머스 데브코스/CS 면접 스터디

[JavaScript] 쿠키와 세션, 토큰 그리고 웹 스토리지

_Woogie 2023. 2. 7. 14:53

클라이언트와 서버 간에 정보를 주고 받는 통신 방법을 HTTP라고 한다.

쿠키와 세션이 왜 등장했는지를 알기 위해 먼저 HTTP의 특징부터 짚고 넘어가면 좋다.

 

 

Stateless한 HTTP

쿠키와 세션이 등장하게 된 배경에는 HTTP 통신의 Stateless한 특징 때문이다.

Stateful과 Stateless
클라이언트와 서버간의 네트워크 통신이 어떻게 이루어지는지에 대한 개념. 즉, 네트워크 프로토콜

세션 상태
  - 클라이언트와 서버간 통신 인증이 된 상태
세션 정보
  - 한 세션 내에서 클라이언트가 서버에 전송할 데이터 정보를 의미함

Stateful
  - 세션이 종료될 때까지, 클라이언트의 세션 정보를 저장하는 네트워크 프로토콜

Stateless
  - 서버가 클라이언트의 세션 상태 및 세션 정보를 저장하지 않는 네트워크 프로토콜

 

Stateless라는 의미는 한마디로 서버가 클라이언트의 정보를 유지하지 않는다는 뜻이다. 클라이언트의 정보를 유지하지 않기 때문에 각 요청을 독립적으로 처리하고, 클라이언트의 이전 요청과 다음 요청을 서로 무관하게 처리한다.

단지 요청에 포함된 데이터를 이용해 그 시점에 적절한 응답만 줄 뿐이다.

 

이런 HTTP의 특징 때문에 매번 요청을 해야하는 번거로움이 있고, 이를 해결하기 위해 쿠키와 세션이 탄생했다.

 

 

쿠키 (Cookie)

쿠키란?

  • 클라이언트(브라우저) 로컬에 저장되는 키와 값이 들어있는 작은 데이터 파일
  • 인증이 유효한 시간을 명시할 수 있고, 유효한 시간 안에서 브라우저가 종료되어도 인증이 유지됨
  • 클라이언트에 300개까지 쿠키 저장가능, 하나의 도메인당 20개의 값, 하나의 쿠키값은 4KB

 

쿠키 구성 요소

  • 이름 : 각각의 쿠키를 구별하는데 사용되는 이름
  • 값 : 쿠키의 이름과 관련된 값
  • 유효시간 : 쿠키의 유지시간
  • 도메인 : 쿠키를 전송할 도메인
  • 경로 : 쿠키를 전송할 요청 경로

 

쿠키 동작 순서

  1. 클라이언트가 페이지를 요청 (사용자가 웹사이트 접근, 로그인)
  2. 서버에서 쿠키 생성
  3. 생성한 쿠키에 정보를 담아 클라이언트에게 전달 (Response Header의 Set-Cookie 속성 사용)
  4. 전달받은 쿠키를 브라우저에 저장, 유효기간이 남았다면 종료되어도 유지됨
  5. 이후 다시 서버에 같은 요청을 할 때 HTTP 헤더에 쿠키를 함께 보냄
  6. 서버는 전달받은 쿠키를 이용하여 해당 요청을 처리하고 (변경사항이 있다면 반영 후) 응답

 

쿠키는 서버가 가지고 있는 것이 아니라 사용자 브라우저에 저장되기 때문에 사용자가 임의로 고치거나 지울 수 있고, 가로채기도 쉬워 보안에 취약하다. 또한 개인 정보가 기록되기 때문에 사생활을 침해할 소지도 있다.

 

이런 단점을 보완해주는 것이 세션이다.

 

 

세션 (Session)

세션이란?

  • 보안이 취약하다는 쿠키의 한계점을 극복하기 위해 사용
  • 쿠키를 기반하여 동작하지만 사용자 정보를 클라이언트(브라우저)가 아닌 서버 측에서 관리함
  • 각 클라이언트에게 고유 ID를 부여하고 그 ID로 클라이언트 인증을 판별, 브라우저를 종료할 때까지 인증상태 유지
  • 사용자에 대한 정보를 서버에 두기 때문에 사용자가 많아질수록 서버 메모리를 많이 차지하게됨

 

세션 동작 순서

  1. 클라이언트가 서버에 접속 시 세션 ID를 발급 받음
  2. 클라이언트는 서버가 발급해준 세션 ID를 쿠키를 이용해서 저장
  3. 다시 서버에 접속할 때, 쿠키에 저장된 세션 ID를 서버에 전달
  4. 서버는 쿠키 정보(세션 ID)로 클라이언트를 판별

 

쿠키와 세션 차이

특징 쿠키 세션
저장 위치 브라우저 서버
저장 형식 Text Object
보안 낮음 높음
속도 빠름 느림
라이브 사이클 설정해둔 유효시간만큼 브라우저 종료시 만료

 

 

세션은 보안이 높다는 큰 장점이 있지만 요청을 할 때 마다 세션 저장소에 세션 ID를 조회하는 작업을 통해서 DB접근이라는 로직이 한번 더 수행되기 때문에  속도가 느리다는 문제가 있다.

이런 문제를 해결하기 위해 나온 것이 JWT토큰이다.

 

 

JWT 토큰

JWT 토큰이란?

토큰은 암호화된 접근 권한이다.

사용자가 서버에 인증이 되면(로그인을 하면) 사용자에게 유효한 사용자라는 토큰을 발행해준다. 그럼 사용자는 이 토큰을 가지고 웹사이트에서 제공하는 여러 기능들을 이용할 수 있다.

 

즉, JWT (JSON Web Token)은 인증에 필요한 정보들을 암호화시킨 토큰을 의미한다. 앞서 살펴보았던 세션/쿠키 방식과 유사하게 사용자는 Access Token을 HTTP 헤더에 실어서 서버에 전송한다.

 

토큰은 임의로 생성된 비밀번호 같이 동작한다. 토큰은 제한된 수명을 가지고 있어서 토큰이 한번 만료되면 새로 생성되어야한다.

 

JWT 구성 요소

출처: https://prolog.techcourse.co.kr/studylogs/2272

JWT는 각각의 구성요소가 점(.)으로 구분되어있고, 구성요소는 다음과 같다.

  • Header : 정보를 암호화할 방식(alg), 타입(type) 등
  • Payload : 서버에서 보낼 데이터, 일반적으로 유저 고유 ID 값, 유효기간이 들어감. 디코딩이 가능하기때문에 민감한 정보는 넣지 않는다.
  • Signature : Base64 방식으로 인코딩한 Header, Payload, SECRET KEY를 더해 만든다. SECRET KEY를 알지 못하면 복호화를 할 수 없기 때문에 관리를 잘해야한다.

 

JWT 동작 순서

  1. 사용자 로그인
  2. 서버에서 사용자를 확인한 후, 사용자의 고유한 ID값을 부여하고 기타정보와 함께 Payload에 넣음
  3. JWT 토큰 유효기간 설정
  4. 암호화할 SECRET KEY를 이용해 Access Token을 발급
  5. 사용자는 발급받은 Access Token을 저장하고, 필요한 요청마다 헤더에 실어서 요청
  6. 서버는 요청온 토큰의 Verify Siganature를 Secret Key로 복호화한 후 조작여부, 유효기간을 확인
  7. 검증이 완료되면 payload를 디코딩하여 사용자의 Id에 맞는 데이터를 응답해줌

 

JWT 장/단점

장점

  • 세션/쿠키는 별도의 저장소 관리가 필요하지만 토큰은 발급한 후 검증만 하면 되기 때문에 서버에서 추가 저장소가 필요하지 않다.
  • 확장성이 뛰어나다. 대표적으로 Oauth가 있다. 페이스북/구글 같은 소셜 계정들을 이용하여 다른 웹서비스에서도 로그인이 가능하다.

단점

  • 유효기간이 만료되기 전까지 계속 사용이 가능하다. 쿠키나 세션은 삭제를 하면 되지만 JWT는 유효기간이 지나기 전까지는 정보를 이용할 수 있다는 문제가 있다. 이를 해결하기 위해 유효기간을 짧게 하고 Refresh Token을 새로 발급 받으면 해결이 되긴하다.
  • 문자열 길이가 길기 때문에 인증이 필요한 요청이 많을수록 서버의 자원낭비가 발생한다.

 

그럼 클라이언트는 JWT토큰을 어디에 저장할까?

 

 

웹 스토리지 (LocalStorage 또는 SessionStorage) 와 쿠키

세션 스토리지

- 페이지를 새로고침하거나, 이동해도 토큰이 유지된다. 하지만 새로운 탭에서 접속 시 세션이 나뉘어지고, 브라우저가 종료되면 토큰 정보가 사라진다. 때문에 사용자 경험에 좋지않다.

 

- CSRF 공격엔 안전하다.

자동으로 request에 담기는 쿠키와 다르게 js코드에 의해 헤더에 담기므로 XSS를 뚫지 않는이상 request를 보내기가 어렵다.

 

- XSS에 취약하다.

세션 스토리지는 모든 자바스크립트 코드를 통해 액세스 할 수 있으므로 XSS 공격에 취약하지만 자바스크립트 코드로 제어가 필요하기 때문에 CSRF 공격에서는 안전하다.

 

로컬 스토리지

- 로컬 스토리지는 페이지를 이동하거나, 브라우저를 다시 시작해도 만료 없이 유지된다. (영구성)

세션 스토리지와 동일하게 XSS 공격에 취약하고 CSRF 공격에 안전하다.

 

쿠키

- XSS공격으로부터 Web Storage에 비해 안전하다.

쿠키의 httpOnly 옵션과 Secure(https)옵션이 켜져있으면 JS에서 쿠키에 접근 자체가 불가능하다. 그래서 XSS 공격으로 쿠키 정보를 탈취하는걸 막을 수 있다.

하지만 또, 완전히 안전한 것은 아니다.

자동으로 reuqest에 실리는 쿠키의 특성 상 사용자의 컴퓨터에서 요청을 위조할 수 있기 때문이다.

 

- CSRF 공격에 취약하다.

자동으로 request에 담아서 보내기 때문에 공격자가 request url만 안다면 위조하기 쉽다.

 

최근엔 이런 쿠키의 취약점을 막기 위해 쿠키의 same-site 속성과 js의 fetch api 속성의 기본값으로 request에 쿠키를 싣지 않음으로 설정되어있다.

 

XSS? CSRF?

XSS : 공격자가 의도하는 악의적인 js코드를 피해자 웹 브라우저에서 실행시키는 것
CSRF : 정상적인 request를 가로채 피해자인 척 하고 백엔드 서버에 변조된 request를 보내 악의적인 동작을 수행하는 공격

자세한 내용
XSS
CSRF

 

 

그럼 어떻게 해야 안전한걸까?

가장 좋은 방법은 refresh token을 사용하는 방법이다.

 

refresh token을 httpOnly옵션 쿠키로 설정하고 url이 새로고침 될 때마다 refresh token을 request에 담아 새로운 accessToken을 발급 받는다.

발급 받은 accessToken은 js private variable에 저장한다.

 

이런 방식을 사용하게되면 refresh token이 CSRF에 의해 공격당해도 accessToken은 알 수 없기 때문에 안전하다.

따라서 쿠키를 사용하여 XSS를 막고 refresh token 방식을 이용하여 CSRF를 막을 수 있다.

 

 

 

곧 백엔드랑 협업하는 최종 프로젝트를 진행하게 되는데 오늘 배운 내용을 토대로 사용자 인증을 처리하면 좋겠다는 생각을 했다. 🤗

 

 

출처


 

 

먹는 쿠키 말고 IT 쿠키와 친구들 (세션,토큰,캐시)

사용자 인증에 필요한 정보들 | "쿠키 가지고 인증 진행합니다" "세션 끊긴 거 아니에요?" "토큰이 없어서 인증이 안되는 것 같아요" "캐시 한 번 지워보시면 용량 늘어날 수도 있어요" 서비스를

brunch.co.kr

 

 

쿠키와 세션 개념

노션 페이지(아래 내용과 동일) 개요 쿠키와 세션은 개발자 말고도 인터넷 사용자라면 누구나 많이 들어본 단어입니다. 하지만 개념에 대해서는 많은 사람들이 헷갈려 하기에 쉽고 간단하게 정

interconnection.tistory.com

 

 

우아한테크코스 학습로그 저장소

우아한테크코스 크루들이 배운 내용을 기록하는 학습로그 저장소입니다.

prolog.techcourse.co.kr

 

 

[WEB] 📚 Access Token & Refresh Token 원리 (feat. JWT)

Access Token과 Refresh Token 이번 포스팅에서는 기본 JWT 방식의 인증(보안) 강화 방식인 Access Token & Refresh Token 인증 방식에 대해 알아보겠다. 먼저 JWT(Json Web Token) 에 대해 잘 모르는 독자들은 다음 포

inpa.tistory.com

 

 

JWT는 어디에 저장해야할까? - localStorage vs cookie

이번에 지하철 미션을 만들면서 JWT를 클래스 property에 저장했었는데 리뷰어 분께 해당 부분을 피드백 받으면서 어디에 JWT를 저장하는 것이 좋을까 에 대해 고민해보게 되었다. 0. 기본 지식 JWT Js

velog.io

 

 

🍪 프론트에서 안전하게 로그인 처리하기 (ft. React)

localStorage냐 쿠키냐 그것이 문제로다

velog.io