"쿠키 가지고 인증 진행합니다"
"세션 끊긴 거 아니에요?"
"토큰이 없어서 인증이 안되는 것 같아요"
"캐시 한 번 지워보시면 용량 늘어날 수도 있어요"
서비스를 운영하다보면 은근 자주 듣게 되는 단어들이 있다.
바로 윗 문장에 등장한 세션, 토큰, 쿠키, 캐시라는 친구들이다.
내 평생 쿠키라면, 먹는 쿠키 아니면 네이버웹툰에서 구운 쿠키가 전부인데...
IT 세상에도 쿠키가 등장하다니...
자주 등장하는 친구들이지만 정확히 어떤 의미를 가지고 있고 어떤 차이점이 있는지 모르겠어서 이번 기회에 한 번 각잡고 공부를 해보았다.
1. HTTP의 Statelss한 특성
관련 글을 찾아보니 대부분이 HTTP를 간단하게 먼저 설명하는 것으로 시작하더이다.
모든 내용의 근-본인 것 같아 필자도 여기서부터 공부를 시작한다.
HTTP란 Hyper Text Transfer Protocol의 줄임말로 www 상에서 정보를 주고받는 통신 방법이다.
주로 HTML 문서를 주고받는 데 사용되며, 클라이언트와 서버가 서로 request와 response를 하며 통신한다.
HTTP는 Stateless하다는 특성을 가지는데, Stateless = '비'상태유지.
서버가 클라이언트의 정보를 계속 유지하고 있지 않는다는 의미이다.
예를 들어, 클라와 첫번째 통신에서 데이터를 주고 받았다고 해도, 두 번째 통신에서 클라의 이전 데이터를 유지하지 않는다.
그렇지만 쇼핑몰에서 상품을 장바구니에 담고, 구매하는 상황을 가정해보자.
사용자의 정보를 유지하지 않는다면 우리는 계속해서 로그인을 요구해야하는 상당히 귀찮은 상황이 발생한다. (실제로 이렇다면 아무도 이 쇼핑몰을 이용하지 않을테야)
사용자를 이렇게 귀찮게 만들 수는 없으니, Stateless한 프로토콜을 가지고 Stateful한 서비스를 구현하기 위해 사용되는 것이 바로 쿠키와 세션이다.
미리 스포를 좀 하자면, 쿠키와 세션의 차이점은 정보의 저장 위치다. 쿠키는 클라(=로컬=사용자브라우저)에 저장되고, 세션은 '서버'에 저장된다.
솔직히 말하면, "그냥 처음부터 Stateful하게 서빙하면 안돼?" 의문이 든다.
만약 서버가 사용자의 정보를 계속 들고 있다면, 한 두명의 정보쯤이야 빠르게 주고 받을 수 있을 것이다.
그런데 사용자가 급격하게 증가하게 되면, 기존 서버가 감당하지 못해 다른 서버가 그 기능을 대체하게 될 거고,
사용자가 대체 서버에 응답을 요청했을 때, 대체 서버는 사용자의 정보를 가지고 있지 않아 정상적으로 응답을 할 수 없을 것이다. 그렇다면 서비스는 와장창-되는 것이지!
2. 쿠키 (Cookie)
먹는 쿠키도 아니고, 웹툰 볼 때 구워야하는 쿠키도 아니다. 서버에서 받은 데이터를 임시로 클라에 저장해놓는 것이다.
쿠키가 생긴 이유
HTTP 웹사이트에 해당 페이지의 HTML을 요청하면, 응답을 받는 순간(HTML을 받는 순간) 연결이 끊어진다. 계속해서 사용자의 정보를 들고 있는 게 아니란 의미이다.
예를 들어 사용자가 쇼핑몰에서 랭킹을 보고 있는데, 5위 옷이 괜찮아보여서 상품상세를 클릭하고 다시 랭킹페이지로 나왔다. 어? 그런데 사용자가 5위까지 봤다는 걸 모르는 컴퓨터는 다시 1위부터 랭킹을 보여준다. 이때, 사용자는 불편함을 느끼게 된다.
이런 사용자의 불편함을 방지하기 위해 태어난 것이 쿠키이다. 로그인 정보 같이 유저가 굳이 다시 서버에 다시 요청하기에는 비효율적인 정보를 로컬에 저장해둠으로써 생산성을 높이는 것이 목적이다.
쿠키 통신 방법
(1) 최초 통신에서는 쿠키값이 없으므로, 일단 클라이언트는 Request를 한다
(2) 서버에서 클라이언트가 보낸 Request Header에 쿠키가 없음을 판별하고, 통신 상태(UserID, Password, 조작상태, 방문횟수 등)를 저장한 쿠키를 Response한다
(3) 클라이언트의 브라우저가 받은 쿠키를 생성/보존한다
(4) 두 번째 연결부턴, HTTP Header에 쿠키를 실어서 서버에 Request한다
쿠키 제약 조건
쿠키는 1개의 도메인에 한정되어 있다 ex. 네이버에 의해 생성된 쿠키는 구글로 보내질 수 없다
쿠키는 자동으로 보내질 수 없다. ex. 서버는 원하는 만큼 쿠키를 보낼 수 있고, 브라우저는 자동으로 쿠키를 저장한다. '쿠키를 저장하시겠습니까?'와 같은 팝업창을 보지 못한 이유이다
쿠키는 자동으로 세팅된다. 유저가 세팅할 수 있는 건 없다
클라이언트는 총 300개의 쿠기를 저장할 수 있다
하나의 도메인 당 20개의 쿠키를 가질 수 없다 → 20개가 넘으면 가장 적게 사용되는 것부터 삭제된다
하나의 쿠키는 4KB (4096byte) 저장 가능하다
쿠키의 장점
: 다시 서버에 request할 필요가 없기 때문에 속도가 빠르다
쿠키의 단점
: 로그인 정보 등 사용자의 정보가 저장되는 경우가 많아 보안에 취약하다
쿠키 사용 예시
: 팝업 보지 않기, 사용자 이전 스크롤링이나 뷰 설정 값 등
3. 세션 (Session ID)
서버에 임시로 저장한 파일을 세션이라고 한다. 주로 중요한 데이터를 저장할 때 사용되고, 브라우저를 종료할 때까지 유지된다.
세션 통신 방법
(1) 클라가 서버에 접속 시, 세션 ID를 발급한다.
(2) 서버에서는 클라가 발급해준 세션 ID를 쿠키를 이용해서 저장한다.
(3) 클라이언트는 다시 페이지에 접속할 때, 쿠키에 저장된 세션 ID를 서버에 전달한다.
(4) 서버는 Request Header에 쿠키 정보 (세션 ID)로 클라이언트를 판별한다. 세션 ID를 주고 받을 때는 주로 쿠키를 이용하는 경우가 많다.
세션의 장점
: 클라는 세션 ID만 알고 있고, 서버가 정보를 저장하기 때문에 보안성이 좋다
세션의 단점
: 서버에 거쳐서 정보를 받아야하기 때문에 속도가 느리다.
세션 사용 예시
: 로그인 정보 유지
4. 토큰 (Token, JWT)
토큰은 일종의 암호화된 접근 권한이다. 예를 들어 웹사이트에 로그인을 할 때 사용자가 id와 pw넣으면 서버는 이를 확인 후, 사용자에게 유효한 사용자라는 토큰을 발행해준다. 그럼 사용자는 이 토큰을 가지고 웹사이트에서 제공하는 여러 기능들을 이용할 수 있는 것이다.
좀더 자세히 말하자면, JWT(JSON Web Token)는 인증에 필요한 정보들을 암호화시킨 토큰을 의미한다. 위의 세션/쿠키 방식과 유사하게 사용자는 Access Token을 HTTP 헤더에 실어 서버에 전송한다.
토큰은 임의로 생성된 비밀번호 같이 동작한다. 토큰은 제한된 수명을 가지고 있어서, 토큰이 한 번 만료되면 새로 생성되어야 한다. (Refresh Token)
토큰의 장점
세션/쿠키는 별도의 저장소 관리가 필요하다. 하지만 JWT는 발급한 후 검증만 하면 되기 때문에 추가 저장소가 필요하지 않다.
확장성이 뛰어나다. 토큰 기반으로 하는 다른 인증 시스템에 접근이 가능하다. 예를 들어, Facebook, Google, Microsoft 로그인 등은 모두 토큰 기반으로 인증을 하는데, 권한을 받을 수도, 프로필을 써드파티 웹사이트에 제공하도록 허가할 수도 있다.
토큰의 단점
이미 발급된 JWT에 대해서는 유효기간이 만료되기 전까지 계속 사용이 가능하다. 쿠키나 세션은 악의적으로 이용된 경우 그냥 쿠키를 삭제하면 된다. 하지만 JWT는 유효기간이 지나기 전까지는 정보를 이요할 수 있다는 문제가 있다. 이 경우 Access Token의 유효기간을 짧게 하고, Refresh Token을 새로 발급하면 된다.
JWT는 길이가 길기 때문에 인증이 필요한 요청이 많을 수록 서버의 자원낭비가 발생한다.
로그인이 필요한 서비스라면 사실 인증은 정말 필수적이고 기본적인 기능일 것이다. 하지만 사용자 상태값에 따라 정말 다양한 케이스도 많고 어려운 내용도 많아서, 솔직히 필자는 조금 어려움과 두려움을 느꼈다 ㅠㅠ (역시 쪼렙...)
그래도 이번 기회에 인증과 관련된 개념인 쿠키, 세션, 캐시, 토큰에 대해서 기본적인 의미나마 알게 된 것 같아 다행을 느낀다. (물론 더 깊게 들어가면, 훨씬 더 어려운 개념이겠지 허허)
끝까지 읽어주셔서 감사합니다 :-)
저를 이끌어준 선생님들, 감사합니다.