Network

쿠키(Cookie), 세션(Session), 토큰(Token [JWT])에 대해

범데이 2023. 2. 10. 16:32

개요

 

웹 서비스를 운영하다보면 아래와 같이 자주 듣는 말들이 있다.

 

"인증을 쿠키 방식으로 진행할게요"

"세션 끊긴거 아닌가요?"

"토큰이 없어서 인증이 안되는 것 같아요"

 

바로 쿠키, 세션, 토큰이라는 단어들이다.

HTTP통신에서 이들이 등장한 이유와, 각각이 무엇을 의미하는지 한번 알아보고자 한다.

 

 


1. 쿠키, 세션, 토큰의 등장 이유

HTTP 통신은 요청(Request) -> 응답(Response) 이 종료되면 stateless(상태가 유지되지 않음)한 특징 때문에 연결을 끊는 처리 방식이다.

 

1. Connectionless 프로토콜(비연결 지향)

클라이언트가 서버에 요청을 했을 때, 요청에 맞는 응답을 보낸 후 연결을 끊는 처리 방식이다.

2. Stateless 프로토콜(상태정보 유지 안함)

클라이언트의 상태 정보를 가지지 않는 서버 처리 방식이다. 클라이언트와 첫번째 통신에 데이터를 주고 받았다 해도, 두번째 통신에 이전 데이터를 유지하지 않는다.

 

따라서 로그인을 하고난 뒤에도, 해당 인증 정보를 유지하여 다른 통신들을 지속해 나가기 위해 아래에 다룰 인증 방식들을 사용하게 된다.

 

 

 

2. 쿠키(Cookie)

2.1 쿠키의 개념

쿠키는 크롬이나 사파리 같은 브라우저에 저장되는 작은 텍스트 조각이다. 브라우저는 사용자의 컴퓨터에 설치된 소프트웨어이므로 쿠키는 사용자가 갖고 있는 정보라고 할 수 있다.

 

웹 서핑을 하면서 어떤 사이트에 들어가면 쿠키를 설정하라는 문구를 본 적이 있을 것이다. 이 쿠키 때문에 쇼핑 사이트에 로그인하지 않아도 장바구니에 물건을 담아두거나 검색 기록에서 이전에 임력했던 검색어들을 찾아볼 수 있다. 나의 웹 서핑 내역이 마케팅과 광고에 활용되는 것도 쿠키를 통해 이뤄지는 일이다.

 

ex1: A쇼핑몰 장바구니 - ooo티셔츠, xxx청바지

ex2: B사이트 검색내역: 치킨, 날씨, 롤

ex3: C사이트 팝업 설정: 7일동안 다시 보지 않기

 

출처: https://www.google.com/url?sa=i&url=https%3A%2F%2Fvelog.io%2F%40denmark-choco%2FWeb-Authentication%25EC%259D%25B8%25EC%25A6%259D&psig=AOvVaw3VLeJ3sMRqPWJe6e59whZQ&ust=1676100557690000&source=images&cd=vfe&ved=0CBAQjRxqFwoTCJDisKW3iv0CFQAAAAAdAAAAABAD

위와같이 쿠키에는 사용자에게 맡겨도 되는 정보만 저장한다.

 

 

2.2 인증 절차

이러한 특징을 통해 아래와 같이 인증 절차를 가진다.

  • 서버는 클라이언트의 로그인 요청에 대한 응답을 작성할 때, 클라이언트 측에 저장하고 싶은 정보를 응답 헤더의 set-cookie 에 담는다.
  • 이후 클라이언트가 재요청 할 때마다 저장된 쿠키를 요청 헤더의 cookie에 담아 보낸다.
  • 서버는 쿠키에 담긴 정보를 바탕으로 해당 요청의 클라이언트가 누군지 식별 할 수 있다.

 

 

 

3. 세션(Session)

3.1 세션의 개념

웹사이트를 이용하기 위해 아이디와 비밀번호를 입력해서 로그인하면 해당 사이트에서는 회원에게만 허용된 기능들을 제공한다. 마이페이지를 클릭해서 내 정보를 보거나, 회원 전용 게시판의 글 쓰기 버튼을 클릭해서 질문을 남기거나 댓글을 쓸 수도 있다.

 

문제는 이와 같은 클릭 하나하나는 매번 서버에게 새로 보내는 별개의 요청들이어서 사이트에 로그인을 하는 이전의 행동과 연결되어 있지 않다는 것이다. 다시 말해서 서버는 로그인에 성공한 사용자와 로그인한 다음 마이페이지 버튼을 누른 사용자가 동일 인물임을 알지 못한다는 것이다.

 

따라서 사용자가 사이트에 한번 로그인 하면 유효기간이 끝날 때까지 더 이상 아이디와 비밀번호를 입력하지 않아도 되도록 사용자가 이미 서버로부터 인증받았음을 증명해주는 세션이라는 방법을 사용한다.

 

 

 

3.2 인증 절차

출처: https://www.google.com/url?sa=i&url=https%3A%2F%2Fmslilsunshine.tistory.com%2F169&psig=AOvVaw2WpIN8N_L0_mgdjK0HkaSf&ust=1676099306295000&source=images&cd=vfe&ved=0CBAQjRxqFwoTCKi7kNCyiv0CFQAAAAAdAAAAABAj

사용자가 서버에 로그인을 성공하면 서버는 세션 아이디라는 데이터를 만든다. 예를 들어 '2sf97dhsoeif1'와 같은 식으로 알파벳과 숫자가 혼합된 형식을 갖는다. 서버에서는 영화관에서 티켓을 보관용 부분만 찢어 건네주듯 세션 아이디를 사용자에게 전달하고, 메모리에 아이디 사본을 어떤 사용자의 것인지 적어서 보관한다.

 

이후 사용자는 서버로부터 받은 세션 아이디를 쿠키로 저장한 다음 인증이 필요한 모든 요청에 함께 전달한다. 그리하여 서버에서는 해당 세션 아이디를 함께 받아 어떤 사용자의 요청인지 검증할 수 있다.

 

 

 

 

 

4. 토큰(Token [JWT])

4.1 토큰의 개념

위의 세션 방식은 안전하고 효과적이지만 단점도 있다. 서버는 요청마다 함께 딸려 오는 세션 아이디를 바로바로 확인할 수 있도록 로그인한 사용자의 아이디를 메모리에 저장하는데, 데이터를 빠르게 확인할 수 있지만 대신 공간이 한정되어 있다. 서버에 동시 접속하는 사용자가 수없이 많아지면 메모리 공간이 부족해져서 서버에 부하가 걸리게 되는 문제가 발생할 수 있다.

 

이 방식의 대안은 로그인한 사용자에게 세션 아이디 대신 토큰을 발급해주는 방법이 있다.

JWT(JSON Web Token)방식은 인증에 필요한 정보들을 암호화시킨 토큰을 의미한다. 위의 세션/쿠키 방식과 유사하게 사용자는 Access Token(JWT Token)을 HTTP헤더에 실어 서버에 전송한다. 토큰은 임의로 생성된 비밀번호 같이 동작한다. 제한된 수명을 가지고, 새로운 토큰은 한번 만료되면 새로 생성되어야 한다.(Refresh Token)

 

이러한 토큰에는 특수한 수학적 원리가 적용되어 있어 마치 위조 방지 장치가 있는 지폐처럼 서버만이 유효한 토큰을 발행할 수 있다.

 

 

 

4.2 토큰의 구조

토큰은 헤더(Header), 페이로드(Payload), 서명(Signature) 세 파트를 "." 으로 구분하는 구조이다.

Header

JWT를 검증하는데 필요한 정보를 가진 JSON 객체는 Base64 URL-Safe 인코딩된 문자열이다. 헤더는 jwt를 어떻게 검증(verify)하는가에 대한 내용을 담고 있다. alg는 서명시 사용하는 알고리즘이고, kid는 서명시 사용하는 키(public/private key)를 식별하는 값이다.

 

Payload

JWT의 내용이다. 페이로드에 있는 속성들을 클레임 셋(Claim Set)이라고 부른다. 클레임 셋은 jwt에 대한 내용(토큰 생성자의 정보, 생성일시) 이나 클라이언트와 서버 간 주고받기로 한 데이터들로 구성된다.

 

Signature

점(.)을 구분자로 해서 헤더와 페이로드를 합친 문자열을 서명한 값이다. 서명은 헤더의 alg에 정의된 알고리즘과 비밀 키를 이용해 생성하고 Base64 URL-Safe로 인코딩 한다.

 

 

 

 

4.3 인증 절차

  1. 사용자가 로그인을 한다.
  2. 서버에서는 계정 정보를 읽어 사용자를 확인 후, 사용자의 고유 ID값을 부여한 후 기타 정보와 함께 Payload에 집어 넣는다.
  3. JWT토큰의 유효기간을 설정한다.
  4. 암호화할 Secret Key를 이용해 Access Token을 발급한다.
  5. 사용자는 Access Token을 받아 저장 후, 인증이 필요한 요청마다 토큰을 헤더에 실어 보낸다.
  6. 서버에서는 해당 토큰의 Verify Signature를 Secret Key로 복호화 한 후, 조작 여부, 유효기간을 확인한다.
  7. 검증이 완료되었을 경우, Payload를 디코딩하여 사용자의 ID에 맞는 데이터를 가져온다.

 

 

 

4.4 장단점 및 보안전략

장점

  • Header와 Payload를 가지고 Signature를 생성하므로 데이터 위변조를 막을 수 있다.
  • 인증 정보에 대한 별도의 저장소가 필요없다.(서버 부하 ↓)
  • JWT는 토큰에 대한 기본 정보와 전달할 정보 및 토큰이 검증되었다는 서명 등 필요한 모든 정보를 자체적으로 지니고 있다.
  • 토큰은 한 번 발급되면 유효기간이 만료될 때까지 계속 사용이 가능하다.

단점

  • 쿠키나 세션과 다르게 JWT는 토큰의 길이가 길어 인증 요청이 많아질수록 네트워크 부하가 심해진다.
  • Payload자체는 암호화되지 않기 때문에 유저의 중요한 정보를 담으면 안된다.
  • 토큰을 탈취당하면 대처하기가 까다롭다.
  • 특정 사용자의 접속을 강제로 만료하기가 어렵지만, 쿠키/세션 기반 인증은 서버쪽에서 쉽게 세션을 삭제할 수 있다.

 

보안 전략

1. 짧은 만료 기한 설정

토큰의 만료 시간이 짧으면 탈취되더라도 금방 만료되기 때문에 피해를 최소화 할 수 있다. 하지만 사용자가 자주 로그인해야하는 불편함이 있다.

 

 

2. Sliding Session

예를 들어 로그인하고 글을 작성하는 도중 토큰이 만료 된다면 저장 작업이 정상적으로 작동하지 않고 작성한 글이 날아가는 일이 생기는 등 부편함이 존재한다. Sliding Session은 서비스를 지속적으로 이용하는 클라이언트들에게 자동으로 토큰 만료 기한을 늘려주는 방법이다. 1번의 자주 로그인해야하는 단점을 보완시켜준다.

 

 

3. Refresh Token

클라이언트가 로그인 요청을 보내면 서버는 Access Token과 그보다 만료기간이 긴 Refresh Token을 함께 내려준다. 클라이언트는 Access Token이 만료되었을 때, Refresh Token을 사용하여 Access Token의 재발급을 요청한다. 서버는 DB에 저장된 Refresh Token과 비교하여 유효한 경우 새로운 Access Token을 발급하고, 만료된 경우 다시 로그인 시킨다. 검증을 위해서는 서버에 Refresh Token을 별도로 저장시켜야 한다.

 

 


#References

https://tofusand-dev.tistory.com/89

https://velog.io/@jung5318/%EC%BF%A0%ED%82%A4-%EC%84%B8%EC%85%98-%ED%86%A0%ED%81%B0%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90

https://hongong.hanbit.co.kr/%EC%99%84%EB%B2%BD-%EC%A0%95%EB%A6%AC-%EC%BF%A0%ED%82%A4-%EC%84%B8%EC%85%98-%ED%86%A0%ED%81%B0-%EC%BA%90%EC%8B%9C-%EA%B7%B8%EB%A6%AC%EA%B3%A0-cdn/

 

반응형