본문 바로가기
Computer Science/Network

[Network] Cookies vs Sessions

by happy coding! 2022. 9. 7.
반응형

개요

Cookies vs Sessions

HTTP의 특징과 쿠키와 세션을 사용하는 이유

  1. 사용자가 로그인 페이지에서 로그인
  2. 서버에서 사용자가 보낸 정보가 존재하는 사용자인지 확인
  3. 존재하는 사용자인 경우 유일한 세션 ID를 생성하고 사용자 ID와 매핑정보를 저장
  4. 클라이언트에 세션 ID를 쿠키로 저장하도록 전달
  5. 이후에 클라이언트에서 서버로 요청을 할 때 서버는 request header의 쿠키 정보(세션 ID)를 확인하고 세션 ID와 매핑되는 ID의 사용자로 인식함

기본적으로 HTTP 프로토콜 환경은 connectionless, stateless한 특성을 가집니다. 따라서 서버는 클라이언트가 누구인지 매번 확인해야 합니다. 이러한 HTTP 프로토콜의 특성을 보완하여 서버가 클라이언트를 식별하게 하기 위해 쿠키와 세션을 사용합니다.

HTTP 특징

HTTP (Hypertext Transfer Protocol)는 인터넷 상에서 데이터를 주고 받기 위해 서버/클라이언트 모델을 따르는 통신 규약을 말합니다.

HTTP는 규칙을 정의한 규약서(https://www.rfc-editor.org/rfc/rfc7231) 가  있습니다.

 

위의 HTTP 규약서 링크를 열어서 Abtract의 첫 줄을 보면

 

The Hypertext Transfer Protocol (HTTP) is a stateless application-level protocol

 

즉 HTTP는 비상태 애플리케이션 레벨 프로포콜이라고 명확히 정의하고 있습니다.

이 HTTP 프로토콜에는 비연결성(Connectionless)과 비상태성(Stateless)라는 특징이 있습니다.


이는 서버의 자원을 절약하기 위해 모든 사용자의 요청마다 연결과 해제의 과정을 거치기 때문에 연결 상태가 유지되지 않고, 연결 해제 후에 상태 정보가 저장되지 않는다는 것입니다.

비연결성 (connectionless)

클라이언트가 요청을 한 후 응답을 받으면 그 연결을 끊어버리는 특징입니다.

HTTP는 먼저 클라이언트가 서버에 request를 보내면 서버는 클라이언트에게 요청에 맞는 response를 보내고 접속을 끊는 특성이 있습니다.

 

헤더에 keep-alive라는 값을 주어 커넥션을 재활용하는데 HTTP 1.1에서는 이것이 디폴트 입니다.

HTTP가 TCP 위에서 구현되었기 때문에 (TCP는 연결지향, UDP는 비연결지향) 네트워크 관점에서 keep-alive는 옵션으로 connectionless의 연결 비용을 줄이는 것을 장점으로 비연결지향이라고 합니다.

비상태성 (stateless)

통신이 끝나면 상태를 유지하지 않는 특징입니다.

연결을 끊는 순간 클라이언트와 서버의 통신이 끝나며 상태 정보는 유지하지 않는 특성이 있습니다.

쿠키와 세션은 위의 두가지 특징을 해결하기 위해 사용합니다.

 

예를 들어, 쿠키와 세션을 사용하지 않으면 쇼핑몰 사이트에서 옷을 구매하려고 로그인을 했음에도 페이지를 이동할 때마다 계속 로그인을 해야하지만 쿠키와 세션을 사용했을 경우, 한번 로그인을 하면 그 사용자에 대한 인증을 유지하게 됩니다.

쿠키 (Cookie)

쿠키(cookie) 란 웹 사이트에 접속할 때 서버에 의해 사용자의 컴퓨터에 저장되는 정보를 의미합니다.

웹 사이트는 이렇게 저장된 사용자의 정보를 클라이언트(client)측의 컴퓨터에 남겨서 필요할 때마다 재사용합니다.

즉 특정 호스트에서 생성된 쿠키는 이후 모든 요청마다 서버로 쿠키를 다시 전송합니다.

사용자의 컴퓨터에 마치 과자 부스러기가 남아 있는 것과 같다고 해서 쿠키라는 명칭이 붙었습니다.

현재 이러한 쿠키는 로그인 정보비회원의 장바구니 정보를 저장하는 용도로 많이 활용되고 있습니다.

하지만 사용자의 정보가 컴퓨터에 고스란히 남기 때문에 사생활 침해의 우려가 있으며 보안과 관련된 이슈가 있습니다.

쿠키의 구성 요소

  • 이름: 각각의 쿠키
  • 값: 쿠키의 이름과 관련된 값
  • 유효시간: 쿠키의 유지시간
  • 도메인: 쿠키를 전송할 도메인
  • 경로: 쿠키를 전송할 요청 경로

쿠키의 동작 방식

  1. 클라이언트가 페이지를 요청
  2. 서버에서 쿠키를 생성
  3. HTTP 헤더에 쿠키를 포함시켜 응답함
  4. 브라우저가 종료되어도 쿠키 만료 기간이 있다면 클라이언트에서 보관하고 있음
  5. 같은 요청을 할 경우 HTTP 헤더에 쿠키를 함께 보냄
  6. 서버에서 쿠키를 읽어 이전 상태 정보를 변경할 필요가 있을 때 쿠키를 업데이트하여 변경된 쿠키를 HTTP 헤더에 포함시켜 응답

쿠키 사용 예시

  • 방문 사이트에서 로그인 시 "아이디와 비밀번호르 저장하시겠습니까?"
  • 쇼핑몰 장바구니 기능
  • 자동 로그인
  • 팝업에서 "오늘 더 이상 이 창을 보지 않음" 체크

세션 (Session)

세션(Session) 이란 HTTP 프로토콜을 사용하는 인터넷 사용자가 어떤 웹 사이트를 방문할 경우, 웹 사이트의 여러 페이지에 걸쳐 사용되는 사용자 정보를 저장하는 방법을 의미합니다.
사용자가 브라우저를 닫아 서버와 연결을 끝내는 시점까지를 세션이라고 합니다.

앞서 살펴본 쿠키는 클라이언트 측의 컴퓨터에 모든 데이터를 저장합니다.반면 세션은 서버 내부에 저장되며, 세션의 키값만을 클라이언트 측에 남겨둡니다.

브라우저는 필요할 때마다 이 키 값을 이용하여 서버에 저장된 데이터를 사용하게 됩니다.
저장된 값은 반영구적이며, 사용자가 특정 시간동안 사용하지 않을 경우 폐기될 수 있는 정보입니다.

세션은 쿠키와 마찬가지로 연결 지향 통신을 수행하는데 기초적인 요구사항입니다.
방문자가 웹 서버에 접속해 있는 상태를 하나의 단위로 보고 세션이라고 합니다.

세션의 동작 방식

  1. 클라이언트가 서버에 접속 시 세션 ID를 발급받음
  2. 클라이언트는 세션 ID에 대해 쿠키를 사용해서 저장하고 가지고 있음
  3. 클라이언트는 서버에 요청할 때, 이 쿠키의 세션 ID를 같이 서버에 전달해서 요청
  4. 서버는 세션 ID를 전달받아서 별다른 작업없이 세션 ID로 세션에 있는 클라이언트 정보를 가져와서 사용
  5. 클라이언트는 정보를 가지고 서버 요청을 처리하여 클라이언트에게 응답

세션의 특징

  • 각 클라이언트에게 고유 ID를 부여
  • 세션 ID로 클라이언트를 구분해서 클라이언트의 요구에 맞는 서비스를 제공
  • 보안 면에서 쿠키보다 우수
  • 사용자가 많아질수록 서버 메모리를 많이 차지하게됨
  • 세션은 사용자의 수만큼 서버 메모리를 차지하기 때문에 최근에는 이런 문제들을 보완한 토큰 기반 인증 방식을 사용하는 추세
  • 그중 JWT (JSON Web Token)라는 것이 있음

세션의 사용 예시

  • 로그인 같이 보안상 중요한 작업을 수행할 때 사용

Session과 Cookie의 차이

쿠키의 경우 방문자의 정보를 방문자 컴퓨터의 메모리(클라이언트)에 저장합니다.
예를 들어 방문한 웹 사이트를 저장하거나 비회원의 장바구니 정보 등을 저장하는데 사용합니다.

세션은 방문자의 요청에 따른 정보를 클라이언트가 아닌 웹 서버가 세션 아이디 파일을 만들어 서비스가 돌아가고 있는 서버에 저장을 하는 것을 의미합니다.

  Cookie Session
저장위치 클라이언트 서버
저장형식 text Object
리소스 클라이언트의 리소스 서버의 리소스
용량제한 도메인당 20개, 1쿠키당 4KB 제한없음
만료시점 쿠키 저장시 설정(설정 없을 시 브라우저 종료시 만료) 알 수 없음

세션 사용하기

세션 속성 설정하기: session 객체의 setAttribute() 메서드

session.setAttribute("id", "value");

세션의 속성을 사용하기: session 객체의 getAttribute() 메서드

단 getAttribute() 메서드는 리턴 타입이 Object 타입이므로 사용 시 실제 할당된 객체 타입으로 형 변환(casting)해야함

String id = (String) session.getAttribute("id");

세션의 속성 삭제하기: session 객체의 removeAttribute() 메서드

session.removeAttribute("id");

세션의 모든 속성 삭제: session 객체의 invalidate() 메서드

session.invalidate();

세션 공유 문제

우리가 주로 접속하는 웹 사이트 중에 서버 한 대로 운영되고 있는 곳은 거의 없다시피 합니다. 서버 한 대가 죽으면 비즈니스가 멈추고 엄청난 영업 손실이 발생할 수 있기 때문입니다.
그래서 언제나 클라이언트가 서버에 접속할 수 있도록 서버 여러 대를 동시에 운영하며 가용성을 끌어올립니다.
여러 서버를 동시에 운영하기 위해서는 클라이언트의 요청을 분배시켜주는 장비 또는 시스템이 있어야 합니다.

서버 1에서 클라이언트로부터 최초 요청을 받게 되면 새로운 세션 ID를 만들고 서버1의 메모리에 저장시켜놓습니다. 그런데 다음번 요청이 왔을 때 다른 서버로 요청이 전달되면 세션 정보를 찾을 수 없기 때문에 다시 새로운 세션 ID를 발행해버립니다.

이 상태로는 클라이언트가 원하는 서비스를 받을 수 없게 됩니다.
왜냐하면 최근 받았던 사진을 다시 달라고 요청했을 때 이 요청이 서버1로 전달되느냐 서버2로 전달되느냐에 따라서 결과가 달라지기 때문입니다.

그래서 여러 대의 서버를 동시에 운영하기 위해서는 세션을 동기화할 수 있는 방안을 반드시 마련해야합니다.
이 문제를 해결하기 위해서 크게 3가지 방법이 있습니다.

  1. 클라이언트별로 담당 처리 서버를 지정하는 방법 (Sticky Session)
  2. 서버끼리 자기 서버에 보관하고 있는 세션의 변경 사항을 실시간으로 주고받는 방법 (Session Clustering)
  3. 세션 정보를 서버가 아닌 다른 외부 저장소에 저장하는 방법 (Session Server)

Reference

반응형

댓글