JWT(JSON 웹 토큰)를 사용하는 이유는 무엇입니까? 나타나는 배경


JWT란?

JWT(JSON 웹 토큰)는 웹에서 사용되는 토큰에 대한 표준 사양(RFC 7519)을 의미합니다. 특정 기술 이름이 아니라 HTTP와 같은 표준 정의입니다. 의미를 파고들면 JSON + Web + Token으로 볼 수 있습니다. 먼저 토큰이 JSON 형식으로 생성되었음을 알 수 있습니다. 웹은 웹에서 사용되는 것을 의미합니다. 토큰은 말하자면 티켓과 같습니다.
이제 종합해보면 웹에서 사용되는 토큰(티켓과 같은)이라고 생각할 수 있지만 형식은 JSON입니다. 그럼 이건 어디에 써야 할까요? 일상생활에서 우리는 출근하거나 지하철을 타거나 어디를 가려면 통행증이 필요할 때가 있습니다. 공공장소가 아닌 경우 대부분 ‘인증’ 절차를 거치게 됩니다. 아무도 들어오지 않는다는 뜻입니다. 이 경우 입장권을 제시하거나 입장권을 끊어서 입장하게 됩니다. 웹에서도 거의 동일하게 작동합니다. 웹사이트에 접속하면 서비스를 이용하기 위해 가입하라는 메시지가 표시됩니다. 가입하면 거기에서 무언가를 할 수 있습니다. 이는 위에서 설명한 것과 동일한 프로세스를 통해 수행됩니다. 가입하면 토큰인 입장권을 받습니다.

JWT 등장 배경

JWT는 웹에서 사용되는 최초의 인증 방법입니까? 아니요. 기존 방식(여전히 많이 사용되는 쿠키와 세션)이 있고 불편한 점도 있어서 새로운 인증 방식이 나왔습니다. 이제 기존 인증 방식의 문제점과 JWT가 이를 어떻게 해결할 수 있는지 살펴보겠습니다.


기존 인증 방법 쿠키 및 세션

과거에는 쿠키라는 인증 방식이 먼저 사용되었습니다. 웹 사이트에 액세스할 때 쿠키 허용 여부를 묻는 경고를 받았을 수 있습니다. Chrome이나 Safari와 같은 브라우저에 흔적(데이터)을 남길 수 있습니다. 이 쿠키에 아이디와 비밀번호 정보가 남을 경우 웹사이트에 1회 로그인하면 제공되는 서비스를 이용하실 수 있습니다. 이는 쿠키에 저장된 정보를 기반으로 서버 측에서 인증을 수행할 수 있기 때문입니다. 쿠키는 텍스트 파일 형태로 브라우저에 저장됩니다. 쿠키 자체는 아래에 나열된 제한 사항으로 인해 인증 방법으로 사용하기 어렵습니다.

  • 쿠키에 민감한 정보(아이디, 비밀번호)가 포함되어 있을 경우 노출될 경우 큰 보안 문제가 발생합니다.
  • 쿠키는 조작될 수 있어 적절한 인증을 어렵게 만듭니다.
  • 웹 브라우저마다 쿠키를 저장하는 방법이 다르기 때문에 브라우저 간에 공유하기가 어렵습니다.
  • 쿠키에는 크기 제한(4KB)이 있으므로 원하는 만큼 많은 데이터를 포함할 수 없습니다.
  • 서버에서는 쿠키에 포함된 인증 정보를 매번 확인하는 것이 불편하고, 조작된 데이터가 넘어갈 때 처리할 수 없습니다.

그것이 세션이 존재하게 된 이유입니다. 쿠키는 민감한 정보는 포함하지 않지만 클라이언트가 가질 수 있도록 인증 정보를 포함합니다. 해당 인증정보는 서버에 저장되어 있으며, 요청을 받으면 클라이언트의 인증정보와 서버의 인증정보를 비교한다.
쿠키만 사용하는 것과의 차이점은 민감한 정보가 노출되지 않는다는 것입니다. 그 외에 저장된 정보를 교환하는 인증 프로세스 자체는 크게 변경되지 않았습니다.

Cookie만 사용하는 것과 Cookie&Session을 사용하는 것의 차이점을 예로 들어보겠습니다.
테마파크 입장권을 샀어요. 테마파크에 입장하고 퇴장하려면 입장권을 제시해야 합니다. 하지만 티켓에 제 이름과 전화번호가 적혀 있습니다. 외출했다가 테마파크로 돌아가려면 개인 정보가 포함된 티켓을 제시해야 합니다. 플레이 중 티켓을 쏟을 경우 개인정보가 노출되는 문제가 있습니다. 그래서 테마파크 쪽에서는 티켓을 구매하면 식별 가능한 코드가 적힌 팔찌를 줍니다. 이제 입장하거나 퇴장할 때 팔찌를 보여주기만 하면 입장할 수 있습니다. 그러나 또 다른 문제가 발생합니다. 팔찌의 코드가 유효한지 매번 저장 기록을 확인해야 했습니다.

이렇게 쿠키와 세션을 함께 사용하는 것이 보안상 조금 더 좋습니다. Session ID를 도용하더라도 Session 저장소 전체를 삭제하여 서버 측에서 유효하지 않은 모든 인증을 차단할 수 있기 때문입니다. 그러나 요청이 들어올 때마다 서버 측에서 데이터 조회를 통해 쿠키에 저장된 세션 ID를 확인하는 데 약간의 시간이 걸립니다.

세션 방식의 한계

Session 메서드는 클라이언트의 인증 상태를 서버 측에 저장합니다. 이것이 의미하는 바는 서버가 클라이언트의 상태를 알고 있다는 것입니다. 이것을 상태 저장이라고 합니다. HTTP 통신은 기본적으로 상태 비저장입니다. 이것은 큰 장점으로 작용합니다. 클라이언트측 상태를 알 필요가 없다면 서버측에서는 이와 관련된 어떠한 로직도 입력할 필요가 없고, 관리해야 할 인증 관련 데이터도 사라진다. 즉, 데이터 요청을 받으면 원하는 값만 로직으로 반환하면 된다.

Session을 사용하면 stateful이 되기 때문에 서버를 늘리면 문제가 발생합니다.


그림에서와 같이 서버 수가 증가하면 기존 서버는 별도로 세션 정보를 저장해야 합니다. 이 경우 서버마다 차이가 있을 수 있어 필연적으로 동기화 문제가 발생합니다. 이 문제를 해결하려면 중앙에서 사용되는 인증 서버를 만들어야 합니다. 그런 다음 새 서버는 사용자로부터 요청을 받으면 인증을 위해 인증 서버에 또 다른 세션 확인 요청을 보내야 합니다.
이렇게 Session을 사용하더라도 단점이 있습니다.

  • 세션 저장소에 문제가 있을 경우 인증된 다른 사용자는 인증이 되지 않음 → 해당 사이트에 로그인하여 잘 사용하고 있는데 갑자기 튕겨서 다시 로그인을 요구하는 경우가 있을 가능성이 있음 세션에 문제가 있습니다.
  • 상태 저장이기 때문에 서버가 확장될 때 비효율이 발생합니다.
  • 사용자가 늘어날수록 세션 정보를 저장하는 스토리지도 늘어나 서버의 부담이 커진다.
  • 사용자 요청마다 세션 저장소를 검색해야 하므로 사용자 수가 증가함에 따라 성능 문제가 발생할 수 있습니다.

이 문제를 해결하기 위해 JWT가 등장했습니다.