[네트워크] Cookie, Session, JWT

이신영·2023년 6월 26일

인증,인가 할때 쓴다는것만 알고있고 심층적으로 다뤄보진 않아서 한번 써보도록하자 😀

쿠키(Cookie)

  • 클라이언트에 저장되는 작은 데이터(통상 4kb)
  • key-value로 이루어지고 만료기간, 도메인, 경로 등 을 가짐
  • 클라이언트가 수정할수있음
  • 보안 취약점이 있어서 민감한 정보는 저장하지않음
  • 만료기간동안 보관되는거라 브라우저 닫아도 유지됨
  • 주로 사용되는건 오늘하루 보지않기, 최근 검색 리스트, 사용할 언어 등 = 노출되도 상관없는 정보들?

이거 왜 씀?

  • 방문한 사용자의 정보를 저장하고있어서 번거로운 작업을 편리하게 쓸수있음
  • 웹사이트를 운영하는 입장에서는 쿠키정보로 사용자의 행동과 패턴을 트래킹할 수 있음

    이거 아디다스 홈페이지인데 이거 뜨는게 트래킹하려고 맞음

쿠키의 문제점

  • 쿠키값이 보이니까 보안에 취약함
  • 용량이 작아서 정보의 한계가 있음
  • 브라우저마다 지원형태가 달라서 다른 브라우저에서 저장한 쿠키를 못씀
  • 사용자가 쿠키거부하면 사용못함

세션(Session)

  • 서버측에 저장되는 데이터
  • 용량 제한이 없음(물론 서버 용량에 비례함)
  • 클라이언트는 클라이언트를 구별하고 유지하기위해 세션 식별자를 서버에 전달함. 가끔 오래된 페이지에서 세션이 만료되었다고 나오면 세션유지시간에 제한을 둔것.
  • 서버는 세션에 인증 정보를 가지고있고 내 세션인것을 인증하는 쿠키는 브라우저에 저장됨
  • 쿠키랑은 다르게 창 닫으면 지워짐 왜냐? 서버에 저장되니까

이거 왜 씀?

  • HTTP의 특징인 비연결성(Connectionless)무상태(Stateless)의 한계점을 해결하기위해 씀. 즉, 클라이언트가 서버에 요청하고 서버가 요청을 수행하는 순간에 클라이언트의 정보를 저장하지않은 상태로 접속이 끊기게됨.
    예를들어, 세션이 없는 경우는 웹사이트에 로그인한 다음 웹메일함을 누르는순간 서버는 사용자를 인식못해서 다시 로그인해달라고 함. 세션 되게 중요하죠? 하지만..

세션의 문제점

  • 세션저장소를 쓴다는건 클라이언트의 상태를 서버가 저장한다는 것이고 이건 stateless를 위반하는 문제가 있음.
  • 이 문제로 인해, 만약 scale-out방식으로 서버를 증설할 때 기존 서버에서 인증된 사용자가 새로운 서버에 요청을 보내면 인증기록이 없어서 다시 인증해야하는 문제가 생김. 물론, db를 사용해서 인덱싱하면 되겠지만 여러모로 한계가 있겠죠
  • 서버에서 세션저장소를 사용하다보니 요청이 많아지면 서버가 과부하될수있음

JWT(Json Web Token)

  • 세션의 문제인 용량과 서버확장에 대한 문제를 해결해주는 토큰 기반 인증방식
  • 서버가 토큰을 클라이언트에 보내면 클라이언트는 토큰을 보관하고 요청때마다 헤더에 토큰을 넣어서 보내줌
  • 사용자가 로그인하면 서버는 JWT를 생성하여 클라이언트에게 전달. 이후 클라이언트는 JWT를 헤더에 포함시켜 API 요청을 보냄. 서버는 JWT를 검증하여 사용자의 신원을 확인하고, 필요한 권한 부여를 수행함.

구조

{
  "alg": "HS256",
  "typ": "JWT"
}
  • JWT의 유형과 사용된 암호화 알고리즘을 저장
  • JSON형식으로 인코딩되고 보통 Base64로 인코딩하여 표현함

Payload

{
  "sub": "1234567890",
  "name": "SY LEE",
  "iat": 1516239022
}
  • 토큰에 담을 정보를 담고있는 클레임(Claim)을 포함함.
  • 클레임은 세가지로 나뉨
    • 등록된 클레임 (Registered Claims): 토큰에 대한 표준 클레임으로, 사용자 맘대로 이름지을수있음. 예시로 iss(발급자), exp(만료 시간), sub(인증 주제), aud(클라이언트), iat(발급시각) 등이 있다.
    • 공개 클레임 (Public Claims): 사용자 정의 클레임으로, 충돌을 피하기 위해 URL을 사용함
    • 비공개 클레임 (Private Claims): 서버와 클라이언트 사이에 협의된 클레임으로, 토큰 생성자와 수신자 간의 정보 교환을 위해 사용됨. 이름 충돌 주의해야함.

Signature

HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
  • 서명은 토큰의 내용이 변조되지않았다는 무결성과 발급자에 대한 인증을 보장해줌.
  • 서명을 생성하는 방법은 헤더와 페이로드를 각각 BASE64로 인코딩한 결과를 "."으로 연결해서 문자열을 생성하고 헤더에 정의된 알고리즘과 비밀키를 사용해서 해싱하고 다시 BASE64로 인코딩하여 생성함

복호화 예시

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IlNZIExFRSIsImlhdCI6MTUxNjIzOTAyMn1TZmxLeHdSSlNNZUtLRjJRVDRmd3BNZUpmMzZQT2s2eUpWX2FkUXNzdzVjDQo=

이거 BASE64로 디코딩하면

{"alg":"HS256","typ":"JWT"}{"sub":"1234567890","name":"SY LEE","iat":1516239022}SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

라는 헤더, 페이로드, 서명의 결과가 나옴

이거 왜 씀?

  • 표준화된 형식이기도하고 토큰의 구조도 JSON데이터라서 해석하기 쉽기때문에 확장성이 뛰어남(아마 이게 젤 큰듯)
  • 세션처럼 서버에 저장소를 두지않고 클라이언트에 저장됨
  • 토큰 자체에 사용자의 정보가 저장되어있으니 서버는 검증만 해도됨
  • 세션과 쿠키의 문제점을 해결할 수 있다~ 라고 보면되겠죠?

문제점

  • 물론 토큰자체에 사용자 정보를 담고있으니 정보유출문제가 있을수있음
  • 한번 만들면 삭제하는게 안되니까(Stateless) 만료시간을 지정해야함

요약

쿠키 : 웹 애플리케이션에서 간단한 사용자의 상태를 유지하고싶을 때 쓰면좋음

세션 : 서버측에서 사용자의 상태를 관리하고 클라이언트와 상호작용에 사용자의 세션을 써야할 때 쓰면좋음(서버과부하를 조심)

JWT : 서로 다른 시스템이 인증, 인가를 처리할 때쓰면 좋음(확장성)

profile
후회하지 않는 사람이 되자 🔥

0개의 댓글