[JWT] 토큰 기반 인증 시스템 개요

Updated:

토큰 기반 인증 시스템이란?


토큰 기반 인증은 API를 사용하는 웹서비스 개발에 정말 많이 사용되고 있습니다. 토큰 기반 인증 시스템이 애용되는 이유에는 다음과 같은 이유가 있습니다.

Stateless & scalability.

Stateless 서버를 설명하기에 앞서 그 반대인 Stateful서버가 무엇인지에 대해 알아보겠습니다. Stateful 서버는 클라이언트에게서 요청을 받을 때 마다, 클라이언트의 상태를 계속해서 유지하고, 이 유지한 정보를 서비스 제공에 이용합니다.

예를 들어 세션을 유지하는 웹 서버에서 유저가 로그인을 하게되면 세션에 로그인이 되었다는 정보를 저장해 두었다가 서비스를 제공 할 때에 해당 데이터를 사용하게 됩니다.

Stateless 서버는 반대로 상태 정보를 저장하지 않습니다. 즉, 서버는 클라이언트측에서 들어오는 요청만으로 작업을 처리하게 됩니다. 이렇게 상태가 없는 경우 클라이언트와 서버간의 연결고리가 없기 때문에 서버의 확장성 $($Scalability)이 높아집니다.

인증정보를 다른 어플리케이션에서 사용 가능

네이버, 카카오톡, 구글등의 계정으로 다른 웹서비스에 로그인이 가능합니다. 대표적인 예로는 OAuth가 있습니다.

모바일 어플리케이션에 적합

모바일 어플리케이션 개발에서 쿠키 컨테이너를 사용하는 것 보다는 토큰 기반 인증을 도입하는 것이 더 안전한 API를 만드는데 적합합니다.

토큰 기반 인증 시스템의 등장


이렇게 유용한 토큰이 등장하기 전까지는 어떠한 방식의 인증시스템을 사용했을까요? 과거의 인증방식과 불편했던 점들을 살펴보면서 토큰을 사용하게 된 계기를 알아보겠습니다.

기존 인증시스템 $($서버 기반 인증)

서버 기반 인증시스템에서는 사용자의 정보를 서버측에서 저장하고 있었습니다. 서버는 세션들을 메모리 or 디스크 or 데이터베이스에 담아 관리하였습니다.

여기서 세션이란 로그인등과 같은 유저가 인증을 할때의 기록을 서버에 저장한 것을 의미합니다.

server-token-flow $($서버 기반 인증 시스템의 흐름)

하지만 이러한 세션을 서버에 만들고 저장하는 방식은 저장매체에 무리를 줄 수 있다는 단점이 존재합니다. 예를 들어 세션을 메모리에 저장한다면 로그인 중인 유저의 수가 늘어나는 경우 갑자기 서버의 램이 과부화에 걸리게 됩니다.

세션을 사용하므로써의 또다른 문제점은 서버를 확장하는 것이 어려워진다는 점입니다.

더 많은 트래픽을 처리하기 위해 여러대의 서버 컴퓨터를 추가하게 될때, 세션을 사용하게 된다면 어떤 유저가 로그인을 했을때 그 유저는 처음 로그인했었던, 즉 자신에 대한 세션이 저장되어있는 서버에만 요청을 보내도록 설정을 해야합니다. 하지만 이런 과정은 상당히 복잡합니다.

또 하나의 단점은 Cross-Origin Resource Sharing입니다.

웹 어플리케이션에서 세션을 관리 할 때는 주로 쿠키를 사용하는데, 이 쿠키는 단일 도메인, 서브 도메인에서만 작동하도록 설계되어있습니다. 따라서 여러 도메인에서 쿠키를 관리하는 것은 복잡합니다.

토큰 기반 인증 시스템의 장점

위에서 언급한 서버 기반 인증 시스템의 단점을 계선한 것이 토큰 기반 인증 시스템입니다.

1. 무상태$($stateless)이며 확장성$($scalability)이 있다.
토큰은 클라이언트 사이드에 저장되기 때문에 stateless하며 서버를 확장하기 적합한 환경이 됩니다.

2. 보안성 향상
클라이언트가 서버에 요청을 보낼 때, 더 이상 쿠키를 전달하지 않음으로 쿠키를 사용할 시의 보안상 문제가 사라집니다.

3. 토큰을 통한 서비스간의 권한 공유
토큰을 사용하면 다른 서비스에도 권한을 공유 할 수 있게됩니다. 예를 들어 쇼핑몰 서비스인 무신사의 경우 카카오톡 계정을 통해 로그인을 할 수 있습니다. 또한 토큰에 선택적인 권한만을 부여하여 발급할 수 있습니다. 예를 들어서, 무신사에서 카카오톡 계정으로 로그인을 했을 시에 프로필 정보를 가져오는 권한을 있지만 카톡을 보낼 수 있는 권한을 없습니다.

토큰 기반 시스템의 동작 방식


server-token-work-flow

  1. 유저는 아이디와 비밀번호를 입력하여 로그인을 합니다.
  2. 서버측은 해당 정보를 검증합니다.
  3. 계정정보가 맞다면 서버측은 유저에게 signed$($정상적으로 발급된 토큰임을 인증)토큰을 발급해 줍니다.
  4. 클라이언트측은 서버로 부터 전달받은 토큰을 저장해 두었다가 서버에 요청을 할때마다 토큰을 같이 전달합니다.
  5. 서버는 토큰을 검증하고, 요청에 응답합니다.

Reference
https://velopert.com/2350

Categories:

Updated:

Leave a comment