js

JWT 파헤치기

발전생 2021. 8. 12. 16:39

JWT는 json web token의 줄임말이다

로그인 인증 방식에는 대표적인 두 가지가 있다.

  • 세션 인증 방식
  • 토큰 인증 방식

세션 인증은 로그인 시 유저마다 만들어지는 세션을 저장할 데이터베이스가 필수이다. 서버를 여러 대 사용 중이라면 이 세션 데이터베이스를 공유하고 있어야 한다. 그렇지 않으면 로그인을 해서 세션이 만들어졌지만 다음 요청 시 다른 데이터베이스를 살펴보므로 세션이 없는 줄 알고 다시 로그인을 요청하게 되는 문제가 발생할 수 있다. 매 요청 시 세션을 확인하는 게 일반적이다.

 

토큰 인증은 어디에 토큰을 저장하는 지에 따라 또 나뉘게 된다. 브라우저의 로컬 스토리지나 세션 스토리지에 저장할 수도 있고 브라우저의 쿠키에 저장해서 서버에게 요청을 보낼 때마다 알아서 토큰도 같이 보내지게 할 수 있다.

 

브라우저의 스토리지에 저장하는 캐시 방식은 XSS(corss site scripting)에 취약하다. 이는 토큰이 도둑맞기 쉽다는 말이다. 페이지에 악성 스크립트를 심어 토큰을 빼갈 수 있다.

 

브라우저의 쿠키에 저장하는 방식은 CSRF(cross site request forgery)에 취약하다. 쿠키에 httponly를 true로 설졍하면 자바스크립트로 접근할 수 없으므로 XSS 공격(토큰 훔치기)를 당할 일이 없다. CSRF는 요청 위조로 실 사용자가 하지도 않은 요청을 보내는 것이다. 

 

CSRF보다 XSS가 더 방어하기 까다로워서 쿠키에 토큰을 저장하는 방식이 더 낫다고 한다.

 

토큰에는 access token과 refresh token이 있다.

브라우저의 쿠키에 토큰을 저장하는 거면 access token만을 사용해도 충분해 보인다.

 

refresh token의 주된 사용 목적은 토큰을 브라우저에 저장 시 이상한 행동을 하는 사용자를 최대한 빨리 서버로부터 연결을 끊어놓기 위해서이다. 토큰이 브라우저에 저장되어 있으면 이상한 행동을 하는 사용자의 token을 뺏을 수 없어 브라우저에 저장된 토큰이 만료될 때까지 기다려야만 한다. 그래서 수명이 짧은(보통 n시간) access token은 브라우저에게 주고 보다 수명이 긴(보통 n일) refresh token은 데이터베이스에 저장해놓는다. 이상한 행동을 하는 사용자를 발견하면 데이터베이스에서 유저의 refresh 토큰을 제거하고 차단한다. access token이 만료될 때까지는 할 수 있는 게 없다. (브라우저에 저장 시)