토큰(Token) 기반의 인증 시스템은 인증받은 사용자들에게 토큰을 발급하고, 서버에 요청 시 토큰을 HTTP 헤더에 첨부하여 유효성 검사를 하는 방식이다. 이러한 방식은 인증 정보를 서버에 유지하는 서버 기반 인증과 달리 Stateless 하게 클라이언트의 요청만으로 작업을 처리한다는 장점이 있다. 그러나 쿠키를 다루면서 우리는 클라이언트에 비밀번호와 같은 민감한 정보를 그냥 두면 보안상 좋지 않다는 것을 배웠다.
그렇다면 토큰이 쿠키와 다른 점은 무엇일까?
토큰의 차별점은 바로 암호화되었다는 점이다. 이를 위해 사용하는 것이 바로 JWT(Json Web Token)으로, 인증에 필요한 정보를 암호화시킨 토큰을 의미한다. JWT는 크게 다음 부분으로 구성되어 있다.
출처 : https://www.hahwul.com/2016/01/web-hacking-jwtjson-web-token-jwt-test.html
토큰의 작동 과정은 다음과 같다.
무상태성(Stateless) & 확장성(Scalability)
토큰은 클라이언트 측에 저장되기 때문에 서버는 완전히 Stateless 하며, 클라이언트와 서버의 연결고리가 없으므로 확장하기에 매우 적합하다. 만약 사용자 정보가 서버 측 세션에 저장된 경우에 서버를 확장하여 분산처리한다면, 해당 사용자는 처음 로그인했었던 서버에만 요청을 받도록 설정을 해주어야 한다. 하지만 토큰을 사용한다면 어떠한 서버로 요청이 와도 상관이 없다.
보안성
클라이언트가 서버로 요청을 보낼 때 더는 쿠키를 전달하지 않으므로, 쿠키 사용에 의한 취약점이 사라지게 된다. 하지만 토큰 환경의 취약점이 존재할 수 있으므로 이에 대비해야 한다.
확장성(Extensibility)
시스템의 확장성을 의미하는 Scalability와 달리 Extensibility는 로그인 정보가 사용되는 분야의 확정을 의미한다. 토큰 기반의 인증 시스템에서는 토큰에 선택적인 권한만 부여하여 발급할 수 있으며 OAuth의 경우 Facebook, Google 등과 같은 소셜 계정을 이용하여 다른 웹서비스에서도 로그인할 수 있다.
여러 플랫폼 및 도메인
서버 기반 인증 시스템의 문제점 중 하나인 CORS를 해결할 수 있는데, 애플리케이션과 서비스의 규모가 커지면 여러 디바이스를 호환시키고 더 많은 종류의 서비스를 제공하게 된다. 토큰을 사용한다면 어떤 디바이스, 어떤 도메인에서도 토큰의 유효성 검사를 진행한 후에 요청을 처리할 수 있다. 이런 구조를 통해 assests 파일(Image, html, css, js 등)은 모두 CDN에서 제공하고, 서버 측에서는 API만 다루도록 설계할 수 있다.
세션/쿠키의 경우, 만일 쿠키가 악의적으로 이용된다면, 해당하는 세션을 지워버리면 된다. 하지만 JWT는 한 번 발급되면 유효기간이 완료될 때까지는 계속 사용이 가능하다. 따라서 악의적인 사용자가 유효기간이 지나기 전에 정보를 탈취해 갈 위험이 있다. 이는 Refresh Token을 통해 상대적으로 피해를 줄일 수 있다.
Payload 정보가 제한적이다. Payload는 따로 암호화되지 않기 때문에 디코딩하면 누구나 정보를 확인할 수 있다. 따라서 유저의 중요한 정보들은 Payload에 넣을 수 없다.
세션/쿠키 방식보다 JWT의 길이가 길다. 따라서 인증이 필요한 요청이 많아질수록 서버의 자원낭비가 발생한다.
참고
쉽게 알아보는 서버 인증 1편(세션/쿠키 , JWT)
[Server] 토큰 기반 인증 VS 서버 기반 인증