본문 바로가기
이슈와해결

JWT 토큰 기반의 상태 관리시 로그아웃 처리 문제와 간단한 해결 방법

by Renechoi 2023. 12. 18.

본 글의 탄생 배경

사내에서 JWT 기반의 인증 인가 시스템을 구현할 기회가 있었다. 당시 프로젝트 개발을 구상하는 단계에서 로그아웃에 대한 이슈가 있었다. 당시 해당 이슈를 정리하고 검토하면서 작성한 글이다.

 

결론적으로 JWT의 장점을 유지하면서도 가장 효율적인 대안으로 프론트엔드에서의 처리 방법으로 결정했었다.

 

 


 

개요

인증/인가 설계에 있어 JWT 토큰 기반의 방식을 결정하였습니다.

 

기술 구현에 있어서 토큰을 관리하는 구체적인 방식을 진행하기에 앞서 몇가지 논의 사항이 필요합니다.

 

쟁점 사항

이슈를 다루기 전에 먼저 JWT 방식에 대한 이해가 필요하여 다음과 같이 정리하였습니다.

 

❓ JWT 기반 인증의 기존 방식과의 차이

JWT(JSON Web Token) 기반 인증은 전통적인 서버 기반 인증 방식과 여러 면에서 차이가 있습니다.

 

기존의 방식은 서버, 세션 기반의 인증 방식입니다. 서버는 각 사용자에 대한 세션 정보를 유지하며, 사용자가 로그아웃하거나 세션이 만료될 때까지 이 정보를 관리해야 합니다. 즉, 서버가 사용자의 인증 상태(stateful)를 유지하는 것이 특징입니다.

 

 

 

다음 두 가지가 문제로 지적됩니다.

  1. 유저 증가에 따른 서버 부담 가중
  2. 여러 서버에서의 유저 정보 관리의 어려움 -> MSA 환경에서 확장성 저하

반면, JWT 토큰 기반 인증에서는 비저장(stateless) 방식을 지향합니다. JWT를 사용하면 사용자의 인증 정보가 토큰 형태로 클라이언트에 저장되며, 서버는 상태를 유지할 필요가 없기 때문에 서버의 관리 부담을 줄여줍니다.

 

 

 

토큰 기반 인증 방식은 각 서비스가 독립적으로 운영되어야 하고, 서버 간 상태 정보의 공유가 제한적이기 때문 RESTful API와 마이크로서비스 아키텍처(MSA) 환경에서 유리할 수 있습니다.

 

  • restful 원칙 중 하나인 stateless와 부합
  • 분산 환경에서의 유연성 -> 클라이언트가 토큰을 가지므로 어떤 서버로 요청이 가더라도 인증 유지 (현재 관련 업무에서는 물론 한 프로젝트만을 대상으로 하지만, 그렇더라도 독립성 강화의 이점 )

위의 이점들 외에도 실질적인 구현에 있어서, 로그인 상태에서 비밀번호를 변경한다거나, 여러 기기에서의 로그아웃을 구현하는 문제로 확장시켜 생각해볼 때에 stateless 기반의 인증 방식은 다양한 이점을 제공합니다.

 

이와 같이 JWT 기반의 토큰 방식에서는 토큰 내부에 인증에 필요한 정보들을 암호화하여 담고 있으므로 서버는 별도의 db를 이용해 토큰을 관리할 의무가 없습니다. 그러나 이 부분에서 다음과 같은 문제가 발생합니다.

 

❗️ 로그아웃의 문제

stateless 특성에 따라 서버가 클라이언트의 인증 상태를 직접 관리하지 않기 때문에 JWT 기반 인증 시스템에서는 로그아웃 기능에 있어서 이슈가 발생합니다.

 

클라이언트에서 로그아웃 요청이 오더라도 이미 발급된 토큰들에 대한 관리가 안된다는 것입니다. 기존의 방식으로라면 해당하는 토큰들에 대한 만료처리를 함으로써 인증에서 유효성 처리를 할 수 있었을 것입니다. stateless한 토큰에 대해서는 그 유효기간이 끝날 때까지 계속해서 유효하게 남아 있게 되는 문제가 발생합니다. 즉, refresh token이 만료되지 않는 한 계속해서 access token을 발급하게 됩니다.

🔎 대안들

이 문제를 해결하기 위한 방안으로 다음과 같은 3가지 접근을 생각해볼 수 있었습니다.

1. 프론트엔드에서 토큰 삭제

  • 가장 간단한 방법
  • 클라이언트 측에서 말 그대로 토큰을 삭제하여 '로그아웃'을 구현

2. 토큰 블랙리스트 관리

  • JWT가 아직 만료되지 않은 상태에서 로그아웃 요청이 오는 경우, 서버 측에서 해당 토큰을 블랙리스트로 처리
  • 인증 필터에서 매 요청마다 토큰이 블랙리스트에 해당하는 토큰인지를 확인해야 함

3. 리프레시 토큰의 기간 만료처리

  • 요점은 사용자가 로그아웃을 요청할 때 리프레시 토큰을 무효화하여, 해당 사용자가 더 이상 새로운 엑세스 토큰을 발급받지 못하도록 하는 방식

 

🌀 트레이드 오프

1. 프론트엔드에서 토큰 삭제

  • 장점: 구현이 간단하며, 즉각적으로 클라이언트에서 로그아웃이 가능합니다.
  • 단점: 서버 측에서는 여전히 토큰이 유효하므로, 만약 토큰이 타인에게 노출되면 보안 문제가 발생할 수 있습니다. 토큰의 보안에 대한 책임이 강화됩니다.

2. 토큰 블랙리스트 관리

  • 장점: 서버 측에서 토큰을 더욱 효과적으로 관리할 수 있으며, 노출된 토큰에 대한 보안 위험을 최소화할 수 있습니다.
  • 단점: 매 요청마다 블랙리스트를 확인해야 하므로, 사실상 statless한 JWT의 장점을 상실합니다.

3. 리프레시 토큰의 기간 만료처리

  • 장점: 사용자의 로그아웃 요청에 대해 서버 측에서 적극적으로 대응할 수 있으며, 액세스 토큰 재발급의 연속성을 차단함으로써 보안을 강화할 수 있습니다.
  • 단점: 리프레시 토큰에 한해서 확인 로직이 필요하지만, 마찬가지로 stateless한 JWT의 장점을 상실합니다.

2번과 3번 방식을 채택할 경우 서버에서 상태 관리에 관여하게 되므로 사실상 토큰 기반 방식의 장점이 무의미해지는 것이 아닌가 하는 생각이 듭니다.

 

1번의 방식이 토큰 기반 방식의 취지와도 어울리며, 직관적인 방식으로 적절하다고 생각합니다. 따라서 1번 방식을 제안하며 이에 대한 팀내 합의가 필요합니다.

반응형