개요

쿠키와 세션에 대해 이론적인 지식만 있을 뿐. 직접 적용하고 익히니 내가 부족하게 알고 있었음을 느꼈다. 쿠키와 세션에 대해 차근차근 알아보는 시간을 가지자.


(수정 : 20190303)

웹 서비스 관련 공부를 하다보니, 쿠키와 세션을 등한시하면서 모르는 것들에 대해서 다시 한 번 정리할 수 있는 계기가 생겨서 글을 쓰게 되었다.


(수정 : 20190530)


HTTP (HyperText Transfer Protocol)

HTTP 는 인터넷상에서 데이터를 주고받기 위한 서버/클라이언트 모델을 따르는 프로토콜이다. 애플리케이션 레벨의 프로토콜로 TCP/IP 위에서 작동한다. (OSI 계층을 살펴보면, 애플리케이션 계층 아래에 트랜스포트 계층, 네트워크 계층이 존재하기 때문이다.)


HTTP 는 어떤 종류의 데이터든지 전송할 수 있도록 설계되어 있다. 인터넷상에서 흔하게 볼 수 있는 HTML로 작성된 문서는 HTTP로 보낼 수 있다. HTML 문서는 HTTP 로 보낼 수 있는 데이터의 한 종류에 불과하다.


Transfer 는 영어해석 그대로 데이터를 전송하겠다는 의미로 사용된다. 앞에 HyperText 가 붙은 이유는 하이퍼텍스트 기반으로 데이터를 전송하겠다는 의미이며, 링크기반으로 데이터에 접속하겠다는 것이다. 


HTTP 는 서버/클라이언트 모델을 준수하며, 클라이언트에서 서버로 요청(Request) 를 보내면, 서버는 해당 요청(Request) 를 처리해서 응답(Response) 를 한다. 


클라이언트는 서버에 요청하는 클라이언트 소프트웨어가 설치된 컴퓨터를 의미한다. 예를 들면 Chrome, FireFox, Internet Explore 등을 뜻한다. 


서버는 클라이언트의 요청을 받아서, 요청을 해석하고 응답을 하는 소프트퉤어가 설치된 컴퓨터 Apache, nginx, IIS, lighttpd 등이 서버 소프트웨어이다.


Connectless & Stateless

HTTP는 Connectless 방식으로 작동한다. 서버에 연결하고 요청하여 응답을 받으면, 연결을 끊어버린다. 따라서 하나의 자원에 대해서 하나의 연결을 수행하는 것이다. 이러한 특징 때문에 HTTP 는 Connectless  하다고 말한다.

  • Connectless 장점

    • 불특정 다수를 대상으로 하는 서비스에 적합하다. 수십만명이 웹 서비스를 이용하더라도 접속 유지는 최소한으로 할 수 있기 때문에 더 많은 유저의 요청을 처리할 수 있다.

  • Connectless 단점

    • 연결을 끊어버리기 때문에, 클라이언트 이전 상태 정보를 알 수 없다. 이러한 문제 때문에 HTTP 는 Stateless 하다고 말한다. 결과적으로 Connectless 로 인해 Stateless 가 되는 것이다.

접속을 끊고, 상태정보를 유지하지 않는 특징이 있기 때문에 HTTP 는 cookie 를 이용하여 해당 문제들을 해결한다.


Cookie

클라이언트와 서버의 상태 정보를 담고 있는 정보조각이다. 쿠키는 클라이언트 로컬에 저장되는 키와 밸류가 들어가 있는 작은 데이터 파일로서, 클라이언트의 하드(로컬)에 저장된다. 쿠키에는 이름, 값, 만료날짜, 경로정보 등이 들어있으며 쿠키는 일정시간동안 데이터를 저장할 수 있다. 클라이언트는 상태정보를 로컬에 저장하였다가 다시 참조한다.


- 쿠키는 도메인 단위로 구분되며, 서브 도메인의 경우 쿠키는 공유된다.

- 도메인이 같고 포트가 다른 경우에도 쿠키는 공유된다.

- 쿠키에 대한 정보는 HTTP 헤더에 포함되어 전송하기 때문에 네트워크 트래픽을 유발시킬 수 있다.

- 쿠키에는 데이터 크기와 갯수에 대한 제한이 존재한다.


Cookie Process

  1. 브라우저에서 웹페이지 접속

  2. 클라이언트가 요청한 웹페이지를 받으면서 쿠키를 클라이언트 하드에 저장

  3. 클라이언트가 서버에 재 요청을 하는 경우, 웹페이지 요청과 함께 쿠키 값도 같이 전달

  4. 지속적으로 로그인 정보를 가지고 있는 것처럼 사용

Cookie 의 사용사례
자동 로그인, 팝업, 쇼핑몰의 장바구니


Session Cookie vs Permanent Cookie
  • 쿠키에는 두가지 종류의 쿠키가 있다.

  • 웹브라우저를 끄면 사라지는 휘발성 쿠키를 Session Cookie 라 한다.

  • 웹브라우저를 꺼도 사라지지 않는 비휘발성 쿠키를 Permanent Cookie 라 한다.

  • SESSION ID 는 Session Cookie 에 저장되는데, 둘의 차이는 쿠키를 생성하고 Max-Age 혹은 expires 를 설정하냐에 따라서 구분시킬 수 있다. Session Cookie 에는 해당 만료시간이나 Max-Age 에 대한 값이 존재하지 않다.

    결국 웹브라우저를 종료시키면 해당 세션이 사라지기 때문에 브라우저를 다시 실행시킨다면 서버는 다른 클라이언트로 인식할 수 밖에 없다.


Session

일정시간 동안 같은 브라우저로 들어오는 일련의 요구를 하나의 상태로 보고 그 상태를 유지하는 기술, 즉 웹 브라우저를 통해 웹서버에 접속한 이후로 브라우저를 종료할 때까지 유지되는 상태. 클라이언트가 Request 를 보내면, 해당 서버의 엔진이 클라이언트에게 유일한 ID 를 부여한다. 이것이 Session ID 이다.


Session Process

  1. 클라이언트가 서버에 접속 시, 세션 ID 를 발급받음

  2. 서버에서는 클라이언트로 발급해준 Session ID 를 쿠키를 사용하여 저장 (JSP 의 경우 JSESSIONID)

  3. 클라이언트는 HTTP Request 헤더에 SESSION ID 를 포함하여 원하는 리소스를 서버에 요청

  4. 서버는 SESSION ID 를 확인하고 해당 세션을 서버 자원에서 찾아 적절한 응답을 수행 (서버는 SESSION ID 를 식별하여 값에 따라 처리를 달리 할 수 있음)

Cookie vs Session
  • 쿠키는 클라이언트에 파일로 저장, 세션은 서버에 저장
  • 쿠키는 보안에 취약한 반면에 세션은 세션 아이디만 쿠키로 저장하고 그 값을 식별해서 서버에서 처리하기 때문에 비교적 보안에 우수
  • 쿠키는 만료시간을 설정할 수 있으며, 파일로 저장되기 때문에 브라우저가 종료되어도 계속 정보가 남아있음 (왜냐하면 쿠키는 하드에 파일로 저장되기 때문에)
  • 세션은 만료시간을 설정할 수 있으며, 브라우저가 종료되면 만료시간에 상관없이 삭제됨 (왜냐하면 메모리에 세션이 저장되기 때문에)
세션은 어떻게 사용자를 식별하는가.
  1. 클라이언트가 서버에 Resource 를 요청
  2. 서버에서 Http Request 를 통해 쿠키에서 Session ID 를 확인, Session ID 가 없으면 Set - Cookie 를 통해 Session ID 를 새로 발행해서 클라이언트 측으로 응답
  3. 클라이언트는 Http Request 헤더에 Session ID 를 포함하여 원하는 리소스를 서버에 요청
  4. 서버는 Http Request 를 통해 쿠키에서 Session ID 를 확인하고 해당 세션을 서버 자원에서 찾아 적절한 응답을 수행
(2)의 과정에서 만약 처음 접속 도메인을 로컬로 잡아놓고 서버측에서 해당 Session ID 를 확인하면 실제로 null 이 뜬다. 하지만 이후 클라이언트로 넘어가는 시점에서 값을 Session ID를 부여받아 값이 존재하는 것을 확인할 수 있다. 위의 내용들은 크롬 창에서 개발자 도구를 키면 볼 수 있다.


무슨 조건일때 JSESSIONID 가 생성되는가? 에 대한 주제로 stackoverflow에도 관련된 내용이 있다. 아래는 스택오버플로우 사이트에서 질문과 답변 내용을 번역기로 돌린 것이다.

질문자)
언제 JSESSIONID 가 만들어지고, 조건은 무엇인가요? 도메인 당 JSESSIONID 가 만들어지나요 ? 예를 들어서, Tomcat 애플리케이션 서버가 있고, 여러 웹 애플리케이션을 배포하는 경우 컨텍스트별로 다른 JESSIONID 가 생성되나요? 아니면 동일한 도메인에 한해서 웹 애플리케이션간 공유되는 것인가요?

답변자)
세션이 생성될 때 JSESSIONID 쿠키가 생성되고 전송됩니다. 세션은 당신의 코드가 request.getSession() 또는 request.getSession(true) 를 처음으로 호출할 때 생성됩니다. 세션이 없는 경우 세션을 생성하지 않으려면 request.getSession(false) 를 사용하십시오. 이렇게 한다면 당신의 세션이 반환되거나 혹은 null 값이 나옵니다. (해당 의미는 반드시 첫번째 요청에 의해 세션이 만들어지지 않는다는 것을 의미한다.) 

컨텍스트 간에 세션의 공유는 일어나지 말아야 한다. 세션은 컨텍스트 별로 일어납니다.


실제 Tomcat 을 실행시키고 개발자 도구 화면에서 확인한 session ID 값이다. 쿠키에 session 해당 클라이언트에 대한 세션을 식별할 수 있는 키값이 암호화되어 저장된다. 서버는 저 값을 복호화해서 해당 세션이 서버에 존재하는지 여부를 확인할 수 있다.


프로그래밍 언어가 Http 쿠기 이름을 지정하는데 아래와 같이 있다고 한다.

  1. JSESSIONID (JSP)
  2. PHPSESSID (PHP)
  3. CGISESSID (CGI)
  4. ASPSESSIONID (ASP)


추가설명 (20190530)

반복된 설명일 수 있다.

  • 컨테이너는 클라이언트로부터 오는 요청에 대해서 하나의 스레드를 생성한다.
  • 그리고 해당 요청에 대해서 세션 아이디를 부여하고, 이를 쿠키에 담아 클라이언트로 다시 응답한다.
  • 이후 클라이언트의 요청이 오면 쿠키에 담긴 세션 아이디 값을 확인해서 일치하는 HttpSession 을 반환한다. ( 해당 상세 내용은 컨테이너가 내부적으로 실시해서 반환해준다. )



'' 카테고리의 다른 글

20190624 11장 클라이언트 식별과 쿠키  (0) 2019.06.28
20181118 HTTP 상태코드 정리  (0) 2018.11.18
OAuth 2.0 공부 및 참고.  (0) 2018.04.15
20180208 웹 입문.  (0) 2018.02.08
Posted by doubler
,