매우 빠른 템포로 개발을 배우고 있는 상황에서 주위 환경에 끌려가지 않고 지식을 최대한 흡수하기 위해서는 어떻게 해야 할까?
내가 내린 결론은 새로운 개념을 아는 것에 급급하기 보다 내가 구현해 본 기능을 온전히 이해하고 설명할 수 있는지에 집중해야 한다는 것이다.
JWT를 이용하여 로그인을 구현하는 것은 부트캠프 1주차에 이미 해 본 경험이 있다. 하지만 흐름을 정확히 이해하지 못한 채 구현했다는 생각이 들었다. 위에서 말한 조건에 부합하지 못했던 것이다. 그래서 나는 공부를 해야만 하는 이유를 만들기로 했다.
매주 가지는 지식공유 시간에 JWT를 주제로 발표해보겠다 자원한 것이다.
사용자가 이미 회원가입/로그인을 통해 session ID나 토큰 등을 발급받은 상태이고 이 인증도구와 함께 서버로 요청을 보냈다고 가정해보자.
이 둘의 공통점은 인증 과정에서 DB를 거쳐야만 한다는 것이다.
하지만 JWT는? 사용자 인증에 필요한 정보를 토큰 자체에 담고 있어 별도 저장소에 정보를 저장해둘 필요가 없다.
JWT가 담고있는 내용과 원리를 알아보자.
Header, Payload, Signature가 JWT의 구성요소이다.
이들이 JSON형태로 담겨있어서 Json Web Token이다.
이들을 부호화하고 암호화시켜 만들어낸 것이 오른쪽 형태이다.
구체적인 사례를 들어보면 이렇다.
토큰 발급된 이후에 누군가 Payload 정보를 수정한다.
Payload는 조작된 정보가 들어가 있지만 Signature에는 변경되기 전 Payload 내용을 기반으로 암호화된 결과가 저장되어 있다. 조작 후 Payload를 암호화한 결과와는 다른 값이 나온다! 이러한 방식으로 비교하면 서버는 토큰 조작 여부를 쉽게 알 수 있다. 조작된 토큰을 악용하기 어렵다.
인증 관련 정보를 DB에 저장한다면 이용자수가 늘어나는만큼 저장 공간이 더 많이 필요해진다. 또한 인증 시마다 DB를 사용하므로 인증이 몰리면 서버가 과부하될 위험이 있다.
반면 JWT는 별도 저장소가 필요치 않아 서버자원을 절약
할 수 있고 인증 과정에서 다른 곳을 거칠 필요없어 효율적
이다. 인증 정보를 가진 특정 서버에만 트래픽이 몰릴 일도 없다. 서버 부하를 줄이기 좋은 방식
이다.
기존 방식은 다중 서버에서 문제가 발생하기 쉽다.
JWT는 이런 면들을 보완할 수 있다. 특정 서버에 인증에 필요한 정보를 저장해둔 것이 아니라 필요한 정보를 지닌 채로 서버에 도달하기 때문에 Signature 암호화를 해독할 수 있는 secret key가 공유된 서버라면 토큰을 받은 서버가 검증까지 마칠 수 있다. 다른 방식에서 발생할 문제점들을 고려할 필요가 없어 서버 유지·보수, 확장이 편리할 수 있다.
느낀 점
JWT를 알아보다 보니 기존 방식을 응용하거나 다른 방식을 접목시켜 문제점들을 보완하려한 시도들이 많았다는 것을 알게 되었다. 아마 현실에서도 기존 방식의 문제점이 발생할 때마다 새로운 방식을 즉각 도입하기는 쉽지 않을 것이다. 인증방식을 선택할 때 여러 방식을 혼용하거나 구조를 응용하는 방식으로도 부족한 부분을 보완할 수 있겠다는 생각을 했다.
완벽한 인증방식은 없다. JWT가 기존 방식의 문제점을 보완할 수 있는 특징을 가지고 있긴 하지만 단점도 분명 존재한다. 예를들어 JWT는 만료기간이 짧다는 단점을 refresh 토큰 개념을 도입하여 보완할 수 있는데 하나의 문제를 해결한 듯 보이지만 refresh 토큰이 탈취 당했을 때의 리스크가 새롭게 추가된다. 결국 완벽한 인증이란 없으니 장단점을 비교해서 내가 제공할 서비스와 상황에 가장 적합한 인증방식을 선택할 수 있어야 한다. 또한 선택한 인증 방식의 취약점을 인지하고 보완책을 준비할 수 있어야겠다.
Github 하시나용?