TIL 50 | JWT 원리와 장단점

Gom·2021년 4월 10일
24

Web & CS

목록 보기
5/14
post-thumbnail

매우 빠른 템포로 개발을 배우고 있는 상황에서 주위 환경에 끌려가지 않고 지식을 최대한 흡수하기 위해서는 어떻게 해야 할까?
내가 내린 결론은 새로운 개념을 아는 것에 급급하기 보다 내가 구현해 본 기능을 온전히 이해하고 설명할 수 있는지에 집중해야 한다는 것이다.


JWT를 이용하여 로그인을 구현하는 것은 부트캠프 1주차에 이미 해 본 경험이 있다. 하지만 흐름을 정확히 이해하지 못한 채 구현했다는 생각이 들었다. 위에서 말한 조건에 부합하지 못했던 것이다. 그래서 나는 공부를 해야만 하는 이유를 만들기로 했다.
매주 가지는 지식공유 시간에 JWT를 주제로 발표해보겠다 자원한 것이다.

목차


비교

사용자가 이미 회원가입/로그인을 통해 session ID나 토큰 등을 발급받은 상태이고 이 인증도구와 함께 서버로 요청을 보냈다고 가정해보자.

  • session방식은 저장소에 저장해뒀던 session ID를 찾아와 검증하는 절차를 거친다.
  • 기존 토큰 인증은 토큰 자체를 서버에 저장하지는 않지만 토큰을 검증할 때 필요한 관련 정보들을 서버에 저장해두고 있었기에 DB에 접근해야만 했다.

이 둘의 공통점은 인증 과정에서 DB를 거쳐야만 한다는 것이다.

하지만 JWT는? 사용자 인증에 필요한 정보를 토큰 자체에 담고 있어 별도 저장소에 정보를 저장해둘 필요가 없다.


구성요소와 원리

정보를 다 담고 있는 토큰이라니 불안한걸? 어떻게 믿고 사용할까?

JWT가 담고있는 내용과 원리를 알아보자.

Header, Payload, Signature가 JWT의 구성요소이다.
이들이 JSON형태로 담겨있어서 Json Web Token이다.
이들을 부호화하고 암호화시켜 만들어낸 것이 오른쪽 형태이다.

  • Header에는 어떤 알고리즘으로 암호화 할 것인지, 토큰은 어떤 타입을 쓸 것인지와 같은 토큰 관련 정보가 담긴다.
  • Payload에는 사용자 인증 관련 정보가 담긴다. 수정이 가능하여 더 많은 정보를 추가해둘 수도 있다. 그러나 이 곳은 노출과 수정이 가능한 지점이기에 인증이 필요한 최소한의 정보만 담아야한다! 인증에 필요한 최소한의 정보란 아이디, 비밀번호, 개인정보 등이 아니라 이 토큰을 가졌을 때 권한의 범위, 토큰의 발급일과 만료일자 등을 의미한다.
  • Signature 부분이 가장 중요한 역할을 한다. 이 곳에서는 부호화시킨 Header와 Payload를 가지고 발급해준 서버가 지정한 secret key로 암호화 시킨다. 이렇게 하면 토큰을 변조하기가 어려워진다.

구체적인 사례를 들어보면 이렇다.

토큰 발급된 이후에 누군가 Payload 정보를 수정한다.
Payload는 조작된 정보가 들어가 있지만 Signature에는 변경되기 전 Payload 내용을 기반으로 암호화된 결과가 저장되어 있다. 조작 후 Payload를 암호화한 결과와는 다른 값이 나온다! 이러한 방식으로 비교하면 서버는 토큰 조작 여부를 쉽게 알 수 있다. 조작된 토큰을 악용하기 어렵다.


JWT의 장점(필요성)


인증 관련 정보를 DB에 저장한다면 이용자수가 늘어나는만큼 저장 공간이 더 많이 필요해진다. 또한 인증 시마다 DB를 사용하므로 인증이 몰리면 서버가 과부하될 위험이 있다.

반면 JWT는 별도 저장소가 필요치 않아 서버자원을 절약할 수 있고 인증 과정에서 다른 곳을 거칠 필요없어 효율적이다. 인증 정보를 가진 특정 서버에만 트래픽이 몰릴 일도 없다. 서버 부하를 줄이기 좋은 방식이다.


기존 방식은 다중 서버에서 문제가 발생하기 쉽다.

  • session 방식의 경우 요청을 보낸 사용자의 session ID가 저장된 서버에서만 인증이 가능하다. 같은 서비스임에도 서버에 따라 검증 가능 여부가 달라지는 것이다. 이를 해결하기 위해 공용 session 저장소를 만든다던가 sticky session이라하여 사용자의 요청이 session ID를 발급받은 서버로만 가도록하는 방법들이 고안되었다.

  • 기존 토큰 방식은 토큰 검증을 위해 인증 서버를 거치고 있어 인증 서버의 병목현상이 발생할 수 있다.

JWT는 이런 면들을 보완할 수 있다. 특정 서버에 인증에 필요한 정보를 저장해둔 것이 아니라 필요한 정보를 지닌 채로 서버에 도달하기 때문에 Signature 암호화를 해독할 수 있는 secret key가 공유된 서버라면 토큰을 받은 서버가 검증까지 마칠 수 있다. 다른 방식에서 발생할 문제점들을 고려할 필요가 없어 서버 유지·보수, 확장이 편리할 수 있다.


JWT의 단점

  • 외부 공격자가 접근하기 쉬운 위치, 노출 가능한 정보
  • 노출 가능성으로 인해 저장할 수 있는 정보가 제한적이다.
  • 암호화가 풀릴 가능성을 배제할 수 없다.
    -> 암호화가 풀리더라도 토큰을 사용할 수 없도록 만료기간을 짧게 설정한다. 짧게는 5, 6분만 유지되는 경우도 존재하며 길어도 1시간을 넘기지 않는다고 한다.

느낀 점

  1. JWT를 알아보다 보니 기존 방식을 응용하거나 다른 방식을 접목시켜 문제점들을 보완하려한 시도들이 많았다는 것을 알게 되었다. 아마 현실에서도 기존 방식의 문제점이 발생할 때마다 새로운 방식을 즉각 도입하기는 쉽지 않을 것이다. 인증방식을 선택할 때 여러 방식을 혼용하거나 구조를 응용하는 방식으로도 부족한 부분을 보완할 수 있겠다는 생각을 했다.

  2. 완벽한 인증방식은 없다. JWT가 기존 방식의 문제점을 보완할 수 있는 특징을 가지고 있긴 하지만 단점도 분명 존재한다. 예를들어 JWT는 만료기간이 짧다는 단점을 refresh 토큰 개념을 도입하여 보완할 수 있는데 하나의 문제를 해결한 듯 보이지만 refresh 토큰이 탈취 당했을 때의 리스크가 새롭게 추가된다. 결국 완벽한 인증이란 없으니 장단점을 비교해서 내가 제공할 서비스와 상황에 가장 적합한 인증방식을 선택할 수 있어야 한다. 또한 선택한 인증 방식의 취약점을 인지하고 보완책을 준비할 수 있어야겠다.

profile
안 되는 이유보다 가능한 방법을 찾을래요

4개의 댓글

comment-user-thumbnail
2021년 4월 11일

Github 하시나용?

1개의 답글
comment-user-thumbnail
2022년 3월 9일

정리가 잘 되어 있네요! 👍

답글 달기