JWT 기본

기존 Session 처리방식

이전에 JWT를 사용하지 않았다면 사용자의 로그인 정보는 Session을 이용하여 처리했을 것이다.

Spring Security를 통해 로그인 된 사용자의 정보를 가져온다던지, session.getAttribute("로그인한 유저 정보"); 를 가져온다면 session을 이용하는 것이다.

세션을 이용한다면 로그인 한 사용자 정보는 WAS의 세션 저장소에 저장된다.
그렇기 때문에 로그인한 사용자 수가 많을수록, 저장하는 정보가 많을수록 WAS에는 무리가 간다.
문제는 이 뿐만이 아니다.
사용자 정보가 WAS에 귀속되어있기 때문에 WAS가 다중화 되어있고, L4장비 등의 로드밸런싱이 Round Robin과 같은 방식이라면
페이지 동작 중 로그인이 끊기는 문제가 발생한다. (사실 이는 세션클러스터링 방법으로 해결이 가능하다.)


  • 세션 기반 데이터 처리
    톰캣 세션 시퀀스다이어그램

  • 클라이언트가 브라우저 쿠키에서 확인할 수 있는 Tomcat에서 생성해준 JSESSION 데이터
    톰캣 세션 쿠키값




JWT 를 사용한 처리 방식

JWT는 Json Web Token 의 약자로 말 그대로 JSON 형태의 Web Token이다.
https://jwt.io/ 에서 토큰을 디코딩, 검증 해볼 수 있으며 아래와 같이 token 내용은 3개로 구분된것을 확인 할 수 있다.

jwt.io 사이트
좌측은 실제 jwt 이고, 우측은 디코딩 된 내용인데 좌측의 jwt가 ‘.’을 기준으로 총 3구역으로 나뉘어있는걸 볼 수 있다.

헤더에는 JWT의 변조등을 확인하기 위한 암호화 알고리즘의 정보가 들어가며, 본문에는 실제 JWT에 담고자하는 사용자 정보를 담을 수 있다.
맨 아래 서명은 헤더와 본문을 합친 문자열을 정의한 알고리즘과 비밀키를 이용하여 생성한 값으로 JWT를 복호화 하는 과정에서 데이터가 변조되었는지 비교할때 사용된다.


  • JWT기반 처리 방식
    JWT 시퀀스 다이어그램

    생성된 JWT를 쿠키에 담을지, 세션에 담을지, localstorage에 담을지는 많은 관점이 존재한다. 편의상 쿠키에 담는것으로 작성된 다이어그램

  • 클라이언트가 브라우저 쿠키에서 확인할 수 있는 JWT 데이터
    JWT 쿠키값
    이때 JWT 내용은 base64 인코딩만 적용되어있어 쿠키에서 조회되는 value를 그대로 디코딩하면 내용이 노출된다.
    그러므로 민감한정보 (개인정보, 비밀번호 등) 는 jwt에 포함되면 안된다.



JWT를 사용하여 데이터를 쿠키에 저장함으로써

  1. 사용자 정보를 WAS 저장소에 담지 않고 클라이언트 쿠키/로컬스토리지 에 저장하기 때문에 로그인한 사용자가 많아져도 WAS는 부담이 적다.
  2. WAS가 다중화 되어있어도 사용자 정보는 클라이언트 쿠키에서 가져오기 때문에 로드밸런싱 방식 또는 오토스케일링의 영향을 받지 않는다.


그러나 세션과 달리 클라이언트 로컬에 저장되며 통신 시 함께 전송되기 때문에

  1. 저장 혹은 전달 시의 보안에 신경 써야 하며 탈취 되었을때를 대비하여 민감한 정보를 저장하지 않는다.
  2. 매 요청마다 JWT을 변조 여부 확인, payload 데이터 변환 작업을 거쳐야한다. (Filter 또는 Spring Security를 이용)
  3. JWT는 생성 시 만료시간을 정하여 클라이언트에게 전달하기 때문에 서버에서 토큰을 만료시킬 수 있는 방법이 없다. (Refresh Token과 같은 대안 필요)