티스토리 뷰

🚀 쿠키와 세션... 들어본 거는 같은데 언제 주로 사용 ?

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

로그인 이후에 , '누가' 의 상태를 기억하기 위해 쿠키, 세션, 토큰을 사용합니다.

 

  1. Connectionless 프로토콜(비연결 지향)
    클라이언트가 서버에 요청을 했을 때, 요청에 맞는 응답을 보낸 후 연결을 끊는 처리방식이다.
  2. Stateless 프로토콜(상태정보 유지 안 함)
    클라이언트의 상태 정보를 가지지 않는 서버 처리 방식이다. 클라이언트와 첫 번째 통신에 데이터를 주고 받았다 해도, 두번째 통신에 이전 데이터를 유지하지 않는다.

로그인 이후에 예를 들어 회원정보를 수정하는 요청을 보낼 때 서버에게 이 요청을 보낸 사람이 누구인지를 알려줘야 서버에서는 "아 누구의 정보가 수정되었으니 그렇게 DB 정보를 수정해야겠다" 합니다.

그런데 이때 이게 누구의 정보를 수정한다는 요청에 사용자의 id나 index를 실어서 보내게 되면 어떻게 될까요?

만약 이 요청이 서버에게 가는 도중에 누가 탈취하게 되는 위험이 있기 때문에 절대 위와 같이 대놓고 사용자의 정보를 실어서 서버에게 요청을 보내는 방법은 사용하면 안 됩니다.

 

따라서 쿠키나 세션, 토큰과 같은 어떤 사용자를 식별할 수 있는 또 다른 정보를 이용하는 것입니다.

 

🍪 쿠키

쿠키는 공개 가능한 정보를 사용자의 웹 브라우저에 저장합니다. 웹 브라우저에 저장해 놓고 사용자가 요청을 할 때 그 정보를 함께 보내서 서버가 사용자를 식별할 수 있게 해줍니다.

 

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

 

쿠키의 사용 목적

쿠키는 주로 아래의 세 가지 목록을 위해 사용됩니다.

 

  1. 세션 관리(Session Management)
    로그인, 사용자 닉네임, 접속 시간, 장바구니 등의 서버가 알아야 할 정보들을 저장합니다.
  2. 개인화(Personalization)
    사용자마다 다르게 그 사람에 적절한 페이지를 보여줄 수 있습니다.
  3. 트래킹(Tracking)
    사용자의 행동과 패턴을 분석하고 기록합니다.

쿠키의 단점

방문했던 웹 사이트에 대한 정보 및 개인정보가 기록되기 때문에 사생활을 침해할 소지가 있으며, 이를 해소하기 위해서 웹 브라우저 자체에 쿠키 거부 기능이 있습니다. 이러한 쿠키에 대한 거부가 웹 브라우저에 설정되어 있으면, 쿠키 본래의 목적인 웹 브라우저와의 연결을 지속시키는 기능을 수행할 수 없는 경우가 발생합니다.

 

서버가 가지고 있는 것이 아니라 사용자에게 저장되기 때문에, 임의로 고치거나 지울 수 있고, 가로채기도 쉬워 보안이 취약합니다. 따라서 쿠키에는 민감하거나 중요한 정보를 담는 것은 위험합니다.

 

또, 웹 브라우저마다 쿠키에 대한 지원 형태가 다르기 때문에 브라우저간 공유가 불가능합니다.

그래서 이러한 단점을 보완해주는 것이 세션입니다.

🔒 세션

세션은 사용자 정보 파일을 서버에서 관리합니다. 클라이언트가 요청(Request)를 보내면, 해당 서버에서 클라이언트에게 유일한 ID를 부여하는데 이것이 세션ID입니다.

사용자에 대한 정보를 서버에 두기 때문에 보안적인 부분에서 우수합니다.

단, 사용자가 많아질 수록 서버의 부담이 커지게 됩니다.

웹 브라우저가 서버에 접속해서 브라우저를 종료할 때까지 인증상태를 유지합니다. 아이디, 닉네임 등의 정보를 세션에 담아두면 요청이 있을 때마다, DB에 접근할 필요가 없어서 효율적입니다.

세션의 특징

  • 서버에 저장되는 쿠키
  • 웹 브라우저를 닫거나, 서버에서 세션을 삭제했을 때 삭제되므로, 쿠키보다 보안이 좋다
  • 각 사용자는 고유한 세션ID를 부여받는다
  • 세션ID로 사용자를 구분하여 각 사용자의 요구에 맞는 서비스를 제공한다

세션 동작순서

  1. 클라이언트 요청
  2. 서버는 접근 클라이언트의 Request-Header 필드인 Cookie를 확인하여, 클라리언트가 해당 세션ID를 보냈는지 확인
  3. 세션ID가 존재하지 않는다면, 서버는 세션ID를 생성해 클라이언트에게 전송
  4. 서버에서 클라이언트로 준 세션ID를 쿠키를 사용해 서버에 저장
  5. 클라이언트는 재접속시, 이 쿠키를 이용하여 세션ID값을 서버에 전달

 

쿠키와 세션을 비교해보자면

  Cookie Session
저장위치 클라이언트 서버
저장형식 text(string) Object
리소스 클라이언트의 리소스 서버의 리소스
용량제한 도메인당 20개, 1쿠키당 4KB 제한 없음
만료시점 쿠키 저장 시 설정(설정 없을 시에는 브라우저 종료시 만료) 알 수 없음

 

세션의 단점

쿠키를 포함한 요청이 외부에 노출되더라도 세션ID 자체는 유의미한 개인정보를 담고 있지 않습니다. 그냥 고유한 ID일 뿐이라서! 그러나 해커가 세션ID 자체를 탈취하여 클라이언트인척 위장할 수 있다는 한계가 존재합니다.

 

그리고 주요한 단점으로는 서버에서 세션 저장소를 사용하므로 요청이 많아지면 서버에 부담이 커집니다.

 

💰 토큰(JWT)

클라이언트가 서버에 접속을 하면(로그인을 하게 되는 경우도) 서버에서 해당 클라이언트에게 인증되었다는 의미로 '토큰'을 부여합니다. 이 토큰은 유일하며 토큰을 발급받은 클라이언트는 또 다시 서버에 요청을 보낼 때 요청 header에 토큰을 심어서 보내게 됩니다. 그러면 클라이언트로부터 받은 토큰을 서버에게 제공한 토큰과의 일치 여부를 체크하여 인증 과정을 처리하게 됩니다.

세션과의 차이점

기존의 세션 기반 인증은 서버가 파일이나 데이터베이스에서 세션 저장소를 가지고 있어야 하고 이를 조회하는 과정이 필요하기 때문에 사용자가 많아질 경우 서버의 부담이 커질 수 있다고 했습니다.

하지만 토큰은 세션과는 달리 서버가 아닌 클라이언트에 저장되기 때문에 메모리나 스토리지 등을 통해 세션을 관리했던 서버의 부담을 덜 수 있습니다.

 

토큰값은 세션값과 달리 사용자의 정보를 암호화한 형태로 가지고 있습니다.

따라서 세션과는 달리 DB에서 이게 누구의 ID인지 조회하는 과정이 필요 없습니다.

토큰 인증 방식

  1. 사용자가 아이디와 비밀번호로 로그인을 한다
  2. 서버 측에서 사용자(클라이언트)에게 유일한 토큰을 발급한다
  3. 클라이언트는 서버 측에서 전달받은 토큰을 쿠키나 스토리지에 저장해 두고, 서버에 요청을 할 때마다 해당 토큰을 요청 헤더에 포함시켜 전달한다.
  4. 서버는 전달받은 토큰을 검증하고 요청에 응답한다.
    토큰에는 요청한 사람의 정보가 담겨있기에 서버는 DB를 조회하지 않고 누가 요청하는지 알 수 있다

토큰 방식의 단점

  1. 쿠키/세션과 다르게 토큰 자체의 데이터 길이가 길어, 인증 요청이 많아질 수록 네트워크 부하가 심해질 수 있다
  2. Payload 자체는 암호화되지 않기 때문에 유저의 중요한 정보는 담을 수 없다
  3. 토큰을 탈취당하면 대처하기 어렵다(따라서 사용 기간 제한을 설정하는 식으로 예방한다)

JWT(JSON Web Token)?

JWT(JSON Web Token)이란 인증에 필요한 정보들을 암호화시킨 JSON 토큰을 의미합니다. 그리고 JWT 기반 인증은 JWT 토큰(Access Token)을 HTTP 헤더에 실어 서버가 클라이언트를 식별하는 방식입니다.

JWT는 JSON 데이터를 Base64 URL-safe Encode를 통해 인코딩하여 직렬화한 것이며, 토큰 내부에는 위변조 방지를 위해 개인키를 통한 전자서명도 들어있습니다. 따라서 사용자가 JWT를 서버로 전송하면 서버는 서명을 검증하는 과정을 거치게 되며 검증이 완료되면 요청한 응답을 돌려줍니다.

JWT 구조

JWT는 .을 구분자로 나누어지는 세 가지 문자열의 조합입니다.

.을 기준으로 좌측부터 Header, Payload, Signature을 의미합니다.

Header에는 JWT에서 사용할 타입과 해시 알고리즘의 종료가 담겨있으며, Payload는 서버에서 첨부한 사용자 권한 정보와 데이터가 담겨있습니다. 마지막으로 Signature에는 Header, Payload를 Base64 URL-safe Encode를 한 이후 Header에 명시한 해시함수를 적용하고, 개인키(Private Key)로 서명한 전자서명이 담겨있습니다.

 

아래 공식 사이트에서 쉽게 JWT 토큰을 인코딩(생성) 하거나 디코딩 할 수 있습니다.

 

JWT.IO

JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

jwt.io

JWT를 이용한 인증 과정

  1. 사용자가 아이디, 비밀번호를 입력하여 서버에 로그인 인증을 요청한다
  2. 서버에서 클라이언트로부터 인증 요청을 받으면, Header, Payload, Signature를 정의한다
    Header, Payload, Signature를 각각 base64로 한 번 더 암호화하여 JWT를 생성하여 이를 쿠키에 담아 클라이언트에게 발급한다
  3. 클라이언트는 서버로부터 받은 JWT를 로컬 스토리지에 저장한다(쿠키나 다른 곳에 저장 가능)
    API를 서버에 요청할 때 Authorization header에 Access Token을 담아서 보낸다
  4. 서버가 할 일은 클라이언트가 Header에 담아서 보낸 JWT가 내 서버에서 발행한 토큰인지 일치 여부를 확인하여 일치한다면 인증을 통과시켜주고 아니라면 통과시키지 않으면 된다
    인증이 통과되었으므로 페이로드에 들어있는 유저의 정보들을 select해서 클라이언트에 돌려준다
  5. 클라이언트가 서버에 요청을 했는데, 만일 액세스 토큰의 시간이 만료되면 클라이언트는 리프래시 토큰을 이용해서
  6. 서버로부터 새로운 액세트 토큰을 발급 받는다

JWT 토큰 인증 방식이 신뢰성을 가지는 이유

유저 JWT : A(Header) + B(Payload) + C(Signature)일 때 (만일 임의의 유저가 B를 수정했다고 하면 B`로 표시한다)

 

  1. 다른 유저가 B를 임의로 수정 → 유저 JWT : A + B` + C
  2. 수정한 토큰을 서버에 요청을 보내면 서버는 유효성 검사 시행
    ✔️ 유저 JWT : A + B' + C
    ✔️ 서버에서 검증 후 생성한 JWT: A + B` + C` → (signature 불일치)
  3. 대조 결과가 일치하지 않아 유저의 정보가 임의로 조작되었음을 알 수 있다

정리하자면, 서버는 토큰 안에 들어있는 정보가 무엇인지 아는게 중요한 것이 아니라 해당 토큰이 유효한 토큰인지 확인하는 것이 중요하므로, 클라이언트로부터 받은 JWT의 헤더, 페이로드를 서버의 key값을 이요해 시그니처를 다시만들고 이를 비교하며 일치했을 경우 인증을 통과시킵니다.

 

🔦 JWT는 서명(인증)이 목적이다

JWT는 Base64로 암호화를 하기 때문에 디버거를 사용해서 인코딩된 JWT를 1초만에 복호화할 수 있습니다.

복화 하면 사용자의 데이터를 담은 Payload 부분이 그대로 노출되어 버립니다. 그래서 페이로드에는 비밀번호와 같은 민감한 정보는 넣지 말아야 합니다.

여기서 알아야 할 점은 토큰의 진짜 목적은 정보 보호가 아닌, 위조 방지입니다.

바로 위에서 소개했듯이, 시그니처에 사용된 비밀키가 노출되지 않는 이상 데이터를 위조해도 시그니처 부분에서 바로 걸러지기 때문입니다.

JWT 장점

  1. Header와 Payload를 가지고 Signature를 생성하므로 데이터 위변조를 막을 수 있다
  2. 인증 정보에 대한 별도의 저장소가 필요없다
  3. JWT는 토큰에 대한 기본 정보와 전달한 정보 및 토큰이 검증됐음을 증명하는 서명 등 필요한 모든 정보를 자체적으로 지니고 있다
  4. 클라이언트 인증 정보를 저장하는 세션과 다르게, 서버는 무상태(Stateless)가 되어 서버 확장성이 우수해질 수 있다
  5. 토큰 기반으로 다른 로그인 시스템에 접근 및 권한 공유가 가능하다(쿠키와 차이)
  6. OAuth의 경우 Facebook, Google 등 소셜 계정을 이용하여 다른 웹 서비스에서도 로그인할 수 있다
  7. 모바일 애플리케이션 환경에서도 잘 동작한다(모바일은 세션 사용 불가능)

JWT 단점

  1. Self-contained : 토큰 자체에 정보를 담고 있다
  2. 토큰 길이 : 토큰의 Payload에 3종류의 클레임을 저장하기 때문에, 정보가 많아질 수록 토큰의 길이가 늘어나 네트워크에 부하를 줄 수 있다
  3. Payload 인코딩 : Payload 자체는 암호화된 것이 아니라 BASE64로 인코딩된 것이기 때문에, 중간에 Payload를 탈취하여 디코딩하면 데이터를 볼 수 있으므로, payload에 중요한 데이터를 넣지 않아야 한다
  4. Store Token : stateless 특징을 가지기 때문에, 토큰은 클라이언트 측에서 관리하고 저장한다. 때문에 토큰 자체를 탈취당하면 대처하기가 어렵게 된다

 

 

[WEB] 📚 JWT 토큰 인증 이란? - 💯 이해하기 쉽게 정리

Cookie / Session / Token 인증 방식 종류 보통 서버가 클라이언트 인증을 확인하는 방식은 대표적으로 쿠키, 세션, 토큰 3가지 방식이 있다. JWT를 배우기 앞서 우선 쿠키와 세션의 통신 방식을 복습해

inpa.tistory.com

 

728x90
LIST
250x250
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
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
글 보관함