[Web] 세션과 토큰 (JWT) 정리해보기

김예찬·2024년 5월 8일
0

1. 세션

서버단에 로그인 정보를 저장
장점:
1. 서버측에서 상태정보를 관리하므로 상대적으로 보안상 안전하다.
2. 로그인 상태관리를 하기가 편리하다. 예) 특정 사용자를 로그아웃 시켜야할때 세션 id삭제
단점:
1. 서버측 오버헤드가 발생. 여러 사용자가 로그인시 저장해놔야하는 데이터가 많아짐.
2. 세션 저장소에 문제가 생길 경우, 로그인한 사용자가 다시 로그인해야할 수 있다.
메모리형 저장소: 메모리에 데이터를 저장해 빠른 읽고 쓰기가 가능, 휘발성
데이터베이스: 메모리형에 비해 속도가 느리므로 읽기연산이 부담될수있다.
3. 여러대의 서버에서 운영되는 웹사이트의 경우 공용저장소에 저장해야함
(다른 서버에서는 로그인상태를 모를수도 있으므로)

세션을 저장할때 주로 많이 쓰는 Redis의 경우 어느정도 위 문제를 해결할 수 있는 스택으로 보인다.

Redis: 메모리형 저장소로 RAM에 데이터를 저장하는 빠르고 가벼운 데이터베이스.

  • 데이터 스냇샷을 찍어 영속성을 어느정도 보장할 수 있음
  • 다중 서버간의 데이터 공유도 가능함.
    - how? 여러 서버에 레디스 클러스터 구성
  • 각각의 서버는 노드로 여러개의 슬롯(데이터 분산 저장 단위)를 관리
  • 각각의 노드는 통신하며 데이터를 관리

2. 토큰

클라이언트 단에서 로그인 상태 저장(쿠키, 로컬스토리지, 세션스토리지)
클라이언트가 토큰을 서버에 전송하면 서버가 검증

장점:
1. 서버오버헤드가 없다.
2. 무상태성(Stateless) & 확장성(Scalability)
토큰은 클라이언트 측에 저장되므로 서버는 Stateless, 서버 확장에 유리함(서버측에서 저장하는 정보가 없으므로)

단점:
1. 보안적으로 토큰 탈취가능 (서버보단 클라이언트단이 보안이 상대적으로 약할 수 있으므로)
2. 한번 발급한 토큰을 무효화할 방법이 없음(탈취당해도 만료전까지 사용가능)

세션id는 탈취 당한걸 알 경우 서버에서 세션을 삭제할 수 있음.

JWT

JSON Web Token
토큰 기반 인증에서 사용하는 대표적 토큰

Header, Payload, Signature로 구성됨.
각 부분을 base64로 인코딩후 마침표.로 구분

헤더:

  • type: 토큰타입 'JWT'
  • alg: 토큰 검증 암호화 알고리즘

페이로드:

  • 사용자 상태정보
  • 누가 누구에게 발급했는지
  • 유효기간

사용자 상태 정보가 토큰 자체에 담겨있음 self-contained 토큰,
이를 통해 서버는 불필요한 데이터베이스 쿼리를 최소화할 수 있음

서명:

  • 헤더와 페이로드를 base64로 인코딩하고 마침표.로 연결한 것을 서버의 비밀키와 함께 헤더의 암호화 알고리즘을 돌려 얻음.
  • 헤더나 페이로드가 조금만 바뀌어도 서명은 달라지므로 서버가 토큰의 유효성을 검증하는데 사용된다.

검증 방식:
1. 서버가 클라이언트로부터 토큰을 받는다.
2. 해당 토큰의 헤더, 페이로드와 자신의 비밀 키를 이용하여 서명을 계산한다.
3. 해당 토큰의 서명이 방금 계산한 값과 동일한지 검사한다.
4. 만약 동일하지 않다면 요청을 거부하고, 동일하다면 해당 토큰의 유효 기한을 확인한다.
5. 해당 토큰의 유효 기한이 아직 지나지 않았다면, 요청이 허가된다(= 인가).

JWT의 한계

  1. jwt는 상대적으로 보안에 취약한 클라이언트 단에 저장되므로 탈취당하기 쉬움.
    또한 탈취 당한 토큰을 base64로 디코딩하면 페이로드의 정보들을 확인가능하다.
    따라서 jwt의 페이로드에는 최소한의 정보만 담고 민감한 개인정보를 담으면 안된다.

  2. 이미 발급된 jwt를 무효화 할 수 없다.
    서버측에서 토큰을 무효화 할 수 없다. 따라서 탈취한 토큰을 이용해서 유효기간전까지 악의적인 행동이 가능하다. 데이터베이스에서 블랙리스트 jwt목록을 관리할 수 있긴 하지만 매번 쿼리를 필요로하므로 비효율적이다.

0개의 댓글