웹에서 쿠키와 세션
쿠키와 세션을 사용하는 이유
→ HTTP 프로토콜의 특징이자 약점을 보완하기 위해서 사용한다.
HTTP 프로토콜의 특징
- 비연결지향(Connectionless)
- HTTP는 클라이언트가 요청(Request)을 서버에 보내고, 서버는 클라이언트에게 적절한 응답(Response)을 주고 연결(Connection)을 끊는 특성이 있다.
- HTTP1.1 버전에서는 커넥션을 계속 유지하고 요청(Request)에 재활용하는 기능이 추가되었다. (HTTP Header에 keep-alive 옵션을 주어 커넥션을 재활용하게 한다. HTTP1.1 버전에서는 디폴트(default)옵션이다.
- HTTP가 TCP위에서 구현되었기 때문에(TCP는 연결지향, UDP는 비연결지향) 연결지향적이라고 할 수 있다는 얘기가 있어 논란이 있지만, 아직까지는 네트워크 관점에서 keep-alive는 옵션으로 두고, 서버측에서 비연결지향적인 특성으로 커넥션 관리에 대한 비용을 줄이는 것이 명확한 장점으로 보기 때문에 비연결지향으로 알아두었다.)
- HTTP는 클라이언트가 요청(Request)을 서버에 보내고, 서버는 클라이언트에게 적절한 응답(Response)을 주고 연결(Connection)을 끊는 특성이 있다.
- 상태없음(Stateless)
- 커넥션을 끊는 순간 클라이언트와 서버의 통신이 끝나며 상태 정보는 유지하지 않는 특성이 있다.
HTTP는 이 두 가지 특성을 보완하기 위해서 쿠키 와 세션 을 사용하게 되었다.
비연결지향이라는 특성 덕분에 계속해서 커넥션을 유지하지 않기 때문에 서버 리소스 낭비가 줄어드는 것은 아주 큰 장점이지만, 통신할 때마다 새로 커넥션을 만들기 때문에 클라이언트 측면에서는 상태를 유지(ex. 인증에 쓰이는 상태, ...)를 위해 통신할 때마다 어떤 절차를 가져야하는 단점이 생긴다.
심각하게 말하면 만약 쿠키와 세션이 없다면 어떤 페이지에서 다른 어떤 페이지로 넘어갈 때마다 인증을 다시 받아야하는 것이다.
쿠키(Cookie)
쿠키는 클라이언트 로컬(local)에 저장되는 키와 값(key, value)이 들어있는 작은 데이터 파일이다.
쿠키는 서버에서 HTTP Response Header에 Set-Cookie 속성을 이용하여 클라이언트에 쿠키를 제공한다.
쿠키에는 이름, 값, 만료 날짜/시간(쿠키 저장기간), 경로 정보등이 들어있다.
쿠키는 클라이언트의 상태 정보를 로컬에 저장했다가 요청(Request)할 때 참조된다.
쿠키는 서버측에서 만료 날짜/시간을 지정하여 정해진 시간동안 데이터(상태정보)를 유지할 수 있다. (로그인 상태 유지에 활용된다)
세션쿠키(Session Cookie)와 지속 쿠키(Persistent Cookie)
쿠키는 세션 쿠키(Session Cookie) 와 지속 쿠키(Persistent Cookie) 로 나뉜다.
만료 날짜/시간을 지정하지 않으면 항상 유지하라는 것으로 판단하고 지속 쿠키에 저장되고, 만료 날짜/시간을 지정하면 세션 쿠키로 저장된다.
세션 쿠키는 브라우저 메모리에 저장되므로 브라우저가 종료되면 쿠키는 사라지게 된다.
지속 쿠키는 파일로 저장되므로 브라우저가 종료되어도 쿠키는 남아있게 된다.
→ 참고로 세션 쿠키의 값은 보안상 꽤나 안전한 브라우저(ex. 구글 크롬)의 메모리에 저장되기 때문에 보안에 유리하지만 파일로 저장되는 지속 쿠키의 경우 비교적으로 보안에 취약하다.
- 쿠키 프로세스
- 브라우저에서 웹페이지에 접속한다.
- 클라이언트가 요청한 웹페이지를 응답으로 받으면서 HTTP 헤더를 통해 해당 서버에서 제공하는 쿠키 값을 응답으로 준다. (이러면 클라이언트는 해당 쿠키를 저장한다.)
- 클라이언트가 웹페이지를 요청한 서버에 재 요청시 받았던 쿠키 정보도 같이 HTTP 헤더에 담아서 요청한다.
- 서버는 클라이언트의 요청(Request)에서 쿠키 값을 참고하여 비즈니스 로직을 수행한다. (ex 로그인 상태 유지, ...)
- 쿠키 사용 사례
- 자동로그인, 팝업에서 "오늘 더 이상 이 창을 보지 않음" 체크, 쇼핑몰의 장바구니, ...
- 쿠키의 한계
- 클라이언트에 최대 300개 까지 쿠키를 저장할 수 있다.
- 서버 도메인 하나당 최대 20개의 쿠키를 저장할 수 있다.
- 하나의 쿠키 값은 최대 4KB까지 저장할 수 있다.
→ 쿠키는 사용자가 별도로 요청하지 않아도 브라우저(Client)에서 서버에 요청(Request) 시에 Request Header에 쿠키 값을 넣어 요청한다. (=자동이다.)
그렇다고 그 많은 쿠키 값을 굳이 모든 요청에 넣어서 비효율적으로 동작하지는 않는다. 도메인 설정을 통해서 지정한 도메인으로 요청할 때만 쿠키 값이 제공되도록 할 수도 있다.
세션(Session)
서버(Server)에 클라이언트의 상태 정보를 저장하는 기술로 논리적인 연결을 세션이라고 한다.
웹 서버에 클라이언트에 대한 정보를 저장하고 클라이언트에게는 클라이언트를 구분할 수 있는 ID를 부여하는데 이것을 세션아이디라 한다.
- 세션 프로세스
- 클라이언트가 서버에 요청했을 때, 필요에 따라 세션에 클라이언트에 대한 데이터를 저장하고 세션 아이디를 응답을 통해 발급해준다. (브라우저 단에서 관리될 수 있도록 쿠키로 발급하는게 일반적인 구조)
- 클라이언트는 발급받은 세션 아이디를 쿠키로 저장한다. (ex. JSESSIONID)
- 클라이언트는 다시 서버에 요청할 때, 세션 아이디를 서버에 전달하여 상태 정보를 서버가 활용할 수 있도록 해준다.
결과적으로 세션을 통해 클라이언트의 정보는 서버에 두고, 세션 아이디를 이용해서 인증받고 정보를 이용하는 방식이다.
- 세션 사용 사례
- 로그인 정보 유지
쿠키와 세션의 차이
- 저장 위치
- 쿠키는 클라이언트(브라우저)에 메모리 또는 파일에 저장하고, 세션은 서버 메모리에 저장된다.
- 보안
- 쿠키는 클라이언트 로컬(local)에 저장되기도 하고 특히 파일로 저장되는 경우 탈취, 변조될 위험이 있고, Request/Response에서 스나이핑 당할 위험이 있어 보안이 비교적 취약하다. 반대로 Session은 클라이언트 정보 자체는 서버에 저장되어 있으므로 비교적 안전하다.
- 라이프 사이클
- 쿠키는 앞서 설명한 지속 쿠키의 경우에 브라우저를 종료하더라도 저장되어 있을 수 있는 반면에 세션은 서버에서 만료시간/날짜를 정해서 지워버릴 수 있기도 하고 세션 쿠키에 세션 아이디를 정한 경우, 브라우저 종료시 세션아이디가 날아갈 수 있다.
- 속도
- 쿠키에 정보가 있기 때문에 쿠키에 정보가 있기 때문에 서버에 요청시 헤더를 바로 참조하면 되므로 속도에서 유리하지만, 세션은 제공받은 세션아이디(Key)를 이용해서 서버에서 다시 데이터를 참조해야하므로 속도가 비교적 느릴 수 있다.
세션을 주로 사용하면 좋은데 왜 굳이 쿠키를 사용할까?
→ 세션은 서버에 데이터를 저장 즉, 서버의 자원을 사용하기 때문에 서버 자원에 한계가 있고 메모리를 사용하다보면 속도 저하도 올 수 있기 때문이다.
쿠키, 세션은 캐시와 엄연히 다르다
브라우저 캐시는 이미지(.png, .jpg, ...)나 .css, .js파일 등이 사용자의 브라우저에 저장이 되는 것이다.
이를 이용해 같은 자원을 로드(load)해야할 때, 해당 자원을 다시 불러오지 않고 캐시되어 있는 자원을 써서 클라이언트 자원을 아끼는 것이다.
해당 자원이 한 번 브라우저 캐시에 저장되면 다음 필요시에도 브라우저에 있는 걸 재사용하기 때문에 경우에 따라 해당 자원이 변경되어도 변경된 자원을 참조할 수 없는 경우가 생길 수 있다.
따라서 사용자는 브라우저 캐시를 지워주거나 서버에서 클라이언트로 응답을 보낼 때 header에 자원 캐시 만료시간을 명시하는 방법등을 이용하여 캐시를 회피할 수 있다.
보통 쿠키와 세션의 차이를 물어볼 때, 저장위치나 보안에 대해서는 대체적으로 대답을 잘 한다.
그런데 라이프 사이클에 대해서 얘기하지 않는 경우는 많은데 이런 것까지 디테일하게 대답해주는게 좋지 않을까한다.
추가적으로 이론적인 내용뿐만 아니라 실제 사용해보고 사례를 언급하면 더 좋지 않을까한다.
참고 사이트
http://interconnection.tistory.com/74
출처: https://jeong-pro.tistory.com/80?category=793347 [기본기를 쌓는 정아마추어 코딩블로그]
'프로그래밍 > 공부할 내용' 카테고리의 다른 글
제네릭(Generic)에 대한 모든 것(제네릭에 대해서 설명해주세요) (0) | 2021.05.24 |
---|---|
JAVA 컬렉션 (Vector, ArrayList, LinkedList, Set, Map) (0) | 2021.05.24 |
객체 지향 프로그래밍이 뭔가요? (0) | 2021.05.24 |
JAVA String, StringBuffer, StringBuilder 차이점 (0) | 2021.05.24 |
해시(hash)와 암호화(Encryption) 차이점 (1) | 2021.05.24 |