03 Mar 2023

[Web] Token 기반 인증

Token 기반 인증 방식이 생긴 계기 - 서버 기반 인증의 한계

HTTP 프로토콜은 connectionless, stateless 하다는 특징을 가지고 있어 기존에는 세션을 가지고 사용자 정보를 인증했었다. 하지만 사용자가 늘어나면서 다음과 같은 문제점이 대두되었다.

img

서버 메모리

사용자가 인증을 할 때, 서버는 이 기록을 저장해야 한다. 대부분의 경우엔 메모리에 저장하게 되는데 만약 로그인 중인 사용자가 많아지게 된다면 서버 램이 과부하 되는 현상이 발생하게 된다. 이를 피하기 위해 Session을 DB에 저장하는 방식도 있지만, 이 또한 사용자의 수가 많아지면 DB 성능에 무리를 줄 수 있다.

확장성

Session을 사용하면 서버를 확장(더 많은 트래픽을 감당하기 위하여 여러 개의 프로세스를 돌리거나, 여러 대의 서버 컴퓨터를 추가)하는 것이 어려워진다.

CORS (Cross-Origin Resource Sharing)

웹 애플리케이션에서 Session을 관리 할 때 자주 사용되는 Cookie는 단일 도메인 및 서브 도메인에서만 작동하도록 설계되어 있어 쿠키를 여러 도메인에서 관리하는 것은 좀 번거롭다.

이때, CORS (Crosss-Origin Resource Sharing)란, 웹 페이지 상의 제한된 리소스를 최초 자원이 서비스 된 도메인 밖의 다른 도메인으로부터 요청할 수 있게 허용하는 것이다.

이 세 가지의 문제점의 대체재로 나온 것이 바로 Token 기반 인증이다.

토큰 기반 인증의 장점

  1. 무상태성(Stateless) & 확장성(Scalability) 토큰은 클라이언트 측에 저장되기 때문에 서버는 완전히 Stateless하며, 클라이언트와 서버의 연결고리가 없기 때문에 확장하기에 매우 적합하다. 만약 사용자 정보가 서버 측 세션에 저장된 경우에 서버를 확장하여 분산처리 한다면, 해당 사용자는 처음 로그인 했었던 서버에만 요청을 받도록 설정을 해주어야 한다. 하지만 토큰을 사용한다면 어떠한 서버로 요청이 와도 상관이 없다.

    예를 들어, 만약에 세션을 서버측에 저장하고 있고, 서버를 여러대를 사용하여 요청을 분산하였다면, 어떤 유저가 로그인 했을땐, 그 유저는 처음 로그인했었던 그 서버에만 요청을 보내도록 설정을 해야한다. 하지만, 토큰을 사용한다면, 어떤 서버로 요청이 들어가던, 상관이 없다.

    반대로, Stateful 서버는 클라이언트에게서 요청을 받을 때 마다, 클라이언트의 상태를 계속해서 유지하고, 이 정보를 서비스 제공에 이용하는 서버이다. stateful 서버의 예제로는 세션을 유지하는 웹서버가 있다. 예를 들어 유저가 로그인을 하면, 세션에 로그인이 되었다고 저장을 해 두고, 서비스를 제공 할 때에 그 데이터를 사용한다. 여기서 이 세션은, 서버컴퓨터의 메모리에 담을 때도 있고, 데이터베이스 시스템에 담을 때도 있다.

  2. 보안성 클라이언트가 서버로 요청을 보낼 때 더 이상 쿠키를 전달하지 않으므로, 쿠키 사용에 의한 취약점이 사라지게 된다. 하지만 토큰 환경의 취약점이 존재할 수 있으므로 이에 대비해야 한다.

  3. 확장성(Extensibility) 시스템의 확장성을 의미하는 Scalability와 달리 Extensibility는 로그인 정보가 사용되는 분야의 확장을 의미한다. 토큰 기반의 인증 시스템에서는 토큰에 선택적인 권한만 부여하여 발급할 수 있으며 OAuth의 경우 Facebook, Google 등과 같은 소셜 계정을 이용하여 다른 웹 서비스에서도 로그인을 할 수 있다. (예를 들어, 페이스북 계정으로 로그인을 했다면, 프로필 정보를 가져오는 권한은 있어도, 포스트를 작성 할 수 있는 권한은 없게 구현)

  4. 여러 플랫폼 및 도메인 서버 기반 인증 시스템의 문제점 중 하나인 CORS를 해결할 수 있는데, 애플리케이션과 서비스의 규모가 커지면 여러 디바이스를 호환시키고 더 많은 종류의 서비스를 제공하게 된다. 토큰을 사용한다면 어떤 디바이스, 어떤 도메인에서도 토큰의 유효성 검사를 진행한 후에 요청을 처리할 수 있다. 서버 측에서 애플리케이션의 응답 부분에 다음과 같은 헤더만 포함시켜주면 된다.

    Access-Control-Allow-Origin: *
    

    이런 구조를 통해 assests 파일(Image, html, css, js 등)은 모두 CDN에서 제공하고, 서버 측에서는 API만 다루도록 설계할 수 있다.

    또한, Android / iOS 모바일 애플리케이션을 개발 할 때, 안전한 API 를 만들기 위해서 쿠키 컨테이너 대신 토큰 기반 인증을 도입한다면, 인증 시스템 개발의 번거로움을 해결할 수 있다.

토큰 기반 시스템의 작동 원리

1) 사용자가 아이디와 비밀번호로 로그인 2) 서버 측에서 해당 계정 정보를 검증 3) 계정 정보가 정확하다면, 서버 측에서 사용자에게 signed 토큰을 발급

여기서 signed 의 의미는 해당 토큰이 서버에서 정상적으로 발급된 토큰임을 증명하는 signature를 지니고 있음을 의미

4) 클라이언트 측에서 전달 받은 토큰을 저장해두고, 서버에 요청을 할 때 마다, 해당 토큰을 함께 서버에 전달 5) 서버는 토큰을 검증하고, 요청에 응답 6) 웹 서버에서 토큰을 서버에 전달 할 때에는, HTTP 요청의 헤더에 토큰 값을 포함하여 전달

img

Thank You For Reading
SeungJun Jeon

점점 강해지고 있습니다.

comments powered by Disqus