본문 바로가기

NETWORK

쿠키, 세션, JWT, 토큰에 대해 알아보자

참고: https://www.youtube.com/watch?v=tosLBcAX1vk


쿠키에 대해서.
쿠키를 이용해서 서버는 내가 누군가를 알기위해 내가 누군지를 알려주는 정보를 나의 브라우저에 넣을 수 있다. 이렇게 정보를 넣은후 클라이언트에서 어떠한 요청(request)을 서버에 할때마다 쿠키가 그 요청과 함께 서버로 전송된다. 쿠키는 어디에 존재하는 것인가? 쿠키는 http의 헤더부분에 달린다(쿠키안에 세션ID가 있는 것이므로 HTTP의 헤더부분에 세션ID가 저장되는 것이다). 웹브라우저에는 쿠키라는 저장영역이 있어서 내가 따로 어떠한 짓을 하지 않아도 서버로부터 http의 헤더부분에 달려온 쿠키가 브라우저의 쿠키 영역에 자동으로 저장됨.  

쿠키의 특징
1. 쿠키는 도메인 별로 제한된다(유튜브에 관한 쿠키가 있고 네이버에 관한 쿠키가 있고 도메인별로 쿠키가 존재한다는 말). 이 말은 유튜브가 내게 준 쿠키는 (내가 서버로 요청을 보낼때)유튜브로만 전송된다는 뜻이다.

2. 쿠키에는 유효기간이 존재한다. 그리고 그 유효기간은 서버가 정한다.  
3. 쿠키는 인증 뿐만 아니라, 여러가지 정보를 저장할 수 있다. 예를들어 내가 사용하는 브라우저에서 영어로된 페이지를 달라고 요청하면 서버는 나에게 쿠키를 주고 내가 선택한 언어를 저장한다. 이에 따라 다음에 웹사이트를 방문할때 쿠키는 요청과 함께 서버로 보내지고 서버에서는 쿠키가 기억해둔 언어설정의 페이지를 제공하게 되는 것이다.



세션과 쿠키에 대해서.
세션과 쿠키에 대해서 알려면 HTTP프로토콜이 Stateless한  프로토콜임을 기억해야 한다. Stateless란 알고있듯이 서버가 내 상태에 대한 어떠한 정보도 가지고 있지 않다는 것이고 따라서 내가 서버로 보내는 요청들 간에는 어떠한 연관관계도 없다. 

세션이란? 서버에 로그인이 지속되는 상태(내 예측으로는 Session DB에 내 정보가 기록되어 있는 상태가 세션일 것이다).


내가 로그인하기 위해 아이디와 비번을 입력하면 서버에서는 이를 확인후 비번이 맞다면 서버는 세션 DB에 래코드를 하나 생성하여 넣는다. 

이렇게 성공적으로 로그인하면 서버는 세션 ID를 쿠키에 담아 브라우저로 보낸다. 그리고 그 쿠키는 브라우저에 저장된다. 그리고 브라우저에서 어떠한 요청을 하게 될때마다 Session ID를 담은 쿠키는 서버로 자동으로 전달된다. 세션ID는 처음 브라우저를 키면서 서버로 요청을 보내고 응답을 받음으로써 내 브라우저의 쿠키 저장 영역에 Session ID가 생기게 된다. 이 세션 ID는 이후 요청과 응답이란 과정에서 계속 사용되다가 3가지 경우에 사라질 수 있다. 1. 서버측에서 세션DB에 있는 세션을 삭제할때 2. 내가 브라우저를 종료할 때(이 때 서버의 세션 DB에는 그대로 사용자의 정보가 남아있지만 30분 정도 흐르면 지워짐). 3. 30분 정도 지나면 저절로 사라짐 

(복습. 세션이란? 서버에 로그인이 지속되는 상태(내 예측으로는 Session DB에 내 정보가 기록되어 있는 상태가 세션일 것이다. )

 

우리가 어떠한 요청을 Session ID를 담은 쿠키를 통해 서버로 보내면 서버는 세션 ID를 담은 쿠키가 왔다는 것은 알지만 내가 누구인지는 알지 못한다. 내가 누군가를 알수 있는 방법은 세션 DB를 통해 Session ID를 확인하면서 부터이다.

다시 한번 말하지만 브라우저가 유일하게 갖는 것은 Session ID뿐이다. 쿠키는 그저 Session ID를 전달하기 위한 매개체(매개 함수)일 뿐이다.

세션을 이용하여 ios, Android앱을 만들수는 있지만 쿠키는 사용할 수 없다. 왜냐하면 쿠기는 브라우저에만 있는 것이기 때문이다. 쿠키는 네이티브 앱에는 존재하지 않는다. 이렇게 쿠키를 사용할수 없는 경우 우리는 토큰을 이용할 수 있다. 토큰은 그냥 이상하게 생긴 string이다. 쿠키와 마찬가지로 토큰을 서버로 보내면 서버는 세션DB에서 해당 토큰과 일치하는 유저를 찾는다(토큰을 사용하든 쿠키를 사용하든 서버의 세션 DB를 이용하는 것은 같음). 

내가 배운 OSI 7계층의 Presentation Layer(표현 계층)에서 암호화를 한다. 그리고 그 아래 세션(Session) 계층에서하는 것이 인증 체크(Authorization check)이다. 
(복습. 세션이란? 서버에 로그인이 지속되는 상태. 세션ID는 쿠키에 담기고 쿠키는 HTTP프로토콜의 헤더부분에 달린다) 아.. 이제 큰 그림이 그려진다. OSI7계층의 Session계층에서 인증체크를 하는 것이다 그런데 TCP/IP 5계층에서는 응용계층이 Presentation layer, Session layer를 모두 통합했으므로 응용계층의 프로토콜인 HTTP프로토콜이 인증체크까지 하는 것이다. 즉, 이 인증체크라는 것은 내가 따로 프로그래밍 하지 않아도 HTTP프로토콜 자체가 기본적으로 가지고 있는 기능이라는 것. 인증 체크와 암호화는 내가 구현하는 것이 아닌 기존에 구현된 기능이라는 것이다. 

 

세션과 대비되는 것이 JWT(Jason Web Token)이다.

Session VS JWT

세션은 세션DB를 가지고 있어 사용자의 상태를 저장할 수 있어 사용자들을 컨트롤 할 수 있다. 하지만 JWT를 사용하면 세션 DB라는 개념 자체가 없다. 즉, 사용자들을 컨트롤 할수 없는 것이다. 이것이 Session과 JWT가 상반되는 개념으로 사용되는 이유이며 가장 큰 차이점이다. JWT를 사용하면 서버는 유저를 인증하기 위해 많은 일을 하지 않아도 된다.

(참고로 세션방식에서 로드 벨런싱(Load Balancing)이라는 개념이 존재한다. 서버의 과부하를 막기위해 서버를 여러개 두는 것을 의미. 18:00 https://www.youtube.com/watch?v=cv6syIv-8eo&list=PL93mKxaRDidERCyMaobSLkvSPzYtIk0Ah&index=13 )

기본적으로 세션은 서버의 메모리를 사용한다. 세션 DB를 사용한다는 것은 하드디스크를 사용한다는 것이고 이것은 매우 느린 속도로 진행됨.

JWT는 인증을 위해 사용자 정보를 저장하고 그런것 없이 사인 알고리즘을 사용해 브라우저로부터 받은 정보에 사인을 한다. 그리고 그 사인된 정보를 다시 브라우저에게 전송한다. 그리고 나중에 다시 브라우저가 어떤 요청을 토큰과 함께 보내면 서버는 이전에 자신이 사인한 토큰이 변경되었는지를 검증한다. 이것으로 사용자 검증이 이루어 지게 된다.  참고로 세션에서는 유저에 관한 인증을 위해 유저정보를 세션 DB에 저장하지만 JWT에서 서버는 유저를 인증하는데 필요한 정보를 토큰에 저장한다(즉 JWT에서는 세션과는 다르게 DB를 건드리지 않고 정보를 사인하고 전달하는 것이 전부다).

(JWT에 대한 좀 더 자세한 설명은 다음글 참조. https://flexyduck.tistory.com/439 )

참고로 JWT는 암호화된것이 아니다. 누구나 열어서 JWT내용을 볼수 있다. 따라서 비밀정보를 JWT에 두어서는 안되는 것이다.