해피 코딩!

stateless, stateful - 세션과 토큰 인증방식 본문

Network

stateless, stateful - 세션과 토큰 인증방식

지속가능한 성장을 2020. 12. 16. 17:32

요약

stateless는 서버에서 HTTP와 같은 client의 이전 상태를 기록하지 않는 접속
stateful은 서버에서 client의 이전 상태를 기록.

REST 개념에서 각각의 요청은 독립적인 stateless 방식이며 이것은 client가 상태정보를 모두 관리할 책임이 있다.

statelesscaching, load balancing, scale out이 장점이지만, 매 요청마다 상태 정보를 전달 받아야 하기 때문에 네트워크 자원을 소모한며 서버는 정보를 처리하기 위한 작업이 필요하다.

Stateful

stateful

stateless

stateless
HTTP 프로토콜은 요청에 따른 응답을 받으면 연결이 끊어지고 (connectionless)
통신이 종료되면 어떠한 상태도 남지 않는다. (stateless)

따라서 로그인 후 다시 웹 페이지에 접근하면 로그인 상태가 유지되지 않는다는 문제점이 있다.

HTTP 프로토콜의 인증 문제를 해결하기 위해 사용하는 방법으로 세션과 쿠키를 사용한다.

세션

  1. 사용자가 서버에 로그인 request
  2. 서버는 request가 들어오면 DB를 쿼리하여 사용자 검증, 유효할 경우 고유한 ID 값을 부여하고 세션 저장소에 저장한다. 이와 연결되는 세션 ID를 생성하여 response header에 포함시켜 response
  3. 사용자는 서버에서 해당 세션ID를 받아 쿠키에 저장을 한 후 제한된 요청에 접근할 때 마다 쿠키를 request header에 포함시켜 내보낸다.
  4. 서버에서는 쿠키를 받아 세션 저장소에서 검증한 후 요청에 해당하는 데이터를 반환한다.

세션의 특징

쿠키( 서버에 저장된 세션에 접근하기 위한 세션 ID)가 HTTP 요청 중 노출되어도 쿠키 자체에 중요한 정보는 담겨있지 않다. 하지만 쿠키 자체를 훔쳐 세션에 접근하여 중요한 정보를 빼낼 수 있다. 이를 막기 위해 세션에 유효시간을 넣거나 HTTPS를 사용해 요청을 훔쳐도 그 안의 정보를 보기 힘들게 한다.

쿠키를 통해 세션에 접근하면 세션 ID로 사용자를 구분할 수 있으므로 일일히 사용자 정보를 확인할 필요가 없다.

서버에 세션을 저장하기 때문에 사용자 수가 많아지면 서버의 부담이 늘어난다.
또한 서버 확장성(scalability)이 나빠진다.

서버 사양 업그레이드 뿐만 아니라, 늘어나는 트래픽을 감당하기 위해서 여러 프로세스를 돌리거나 여러 대의 컴퓨터를 추가하는 것이 어려워진다.

세션은 서버에서 가진 정보이며 쿠키는 사용자에게 발급된 세션을 열기 위한 ID이다.

인증의 책임을 서버에서 가지기 위해 사용자에게서 쿠키를 받아 세션을 가져온다.

  • client 의 HTTP 요청이 탈취 당하여 쿠키가 해킹당한다면 (세션 하이재킹 공격) 서버는 사용자를 오인하여 정보를 제공한다.

    • 이것을 막기 위하여 HTTPS 를 사용하거나 세션에 유효기한을 건다.

CORS

쿠키는 단일 도메인 및 서브 도메인에서만 작동하도록 설계되어 여러 도메인에서 관리하기 번거롭다.

토큰

세션 기반 인증과는 달리 서버의 토큰을 이용하여 인증을 수행하는 방법

세션 기반 인증의 stateful 서버는 클라이언트로부터 요청이 있을 때 마다 클라이언트의 상태를 유지한다. 사용자가 로그인 하여 인증을 요청하면 stateful 서버는 인증에 성공하였을 때의 결과(세션)을 메모리 또는 데이터베이스에 유지하기 때문에 서버에 부하가 발생할 수 있다.
하지만 토큰 기반 인증은 stateful 서버와 반대적 개념인 stateless 서버를 사용하며 상태 정보를 유지하지 않는다.

서버가 전달받은 토큰을 검증만 하면 되기 때문에 서버의 부담을 줄이고 서비스의 확장성을 높일 수 있다.

  1. 사용자가 로그인 request
  2. 서버는 request가 들어오면 사용자 검증을 통해 유효성을 확인하고 통과한다면 토큰을 response와 반환한다.
  3. 클라이언트는 토큰을 저장, 서버 요청 시 토큰을 request header에 담아 서버에 요청을 보낸다.
  4. 서버는 토큰을 검증 후, 요청에 응답.

토큰의 특징

모바일 앱 사용에 편리

세션 기반 인증을 사용하면 쿠키 매니저를 따로 관리해야 하지만 토큰을 사용하게 된다면 웹 요청 API 헤더에 넣어서 사용을 하기 때문에 쿠키 매니저가 필요하지 않다.

CSRF 방지

사용자가 사이트를 벗어나도 이미 쿠키가 사용자 정보를 가지고 있기 때문에 공격자에게 노출 될 위험이 있다. 공격자가 임의로 다른 URL로 유도하여 비밀번호를 바꾸거나 회원 탈퇴를 할 경우 쿠키가 있기 때문에 서버는 요청을 신뢰하고 작업을 수행하게 된다. 이러한 문제를 해결하기 위해 탈퇴 시 비밀번호를 한 번 더 요구하거나, 토큰과 같은 credentail을 포함한다. 토큰 기반 인증에서는 헤더 내 토큰이 포함되어 CSRF를 방지한다.

서버 확장 문제 해결

여러개의 서버에서 한 세션이 첫 번째 서버에 생성되었다고 가정하였을 때, 새로운 요청이 발생하고 그 요청이 다른 서버에 전달되면 해당 서버에는 세션 정보가 없어 unauthrized 응답을 받는다.
stick 세션(같은 서버에 세션을 계속 연결시키는 방식)을 사용하여 해결할 수 있지만, 토큰 기반 요청에서 요청 토큰은 모든 요청, 모든 서버가 가로채기 때문에 자연스럽게 이러한 문제가 해결된다.

토큰방식의 문제

stateless 한 토큰의 특성 떄문에 토큰을 강제로 만료할 수 없다.
토큰이 공격자에게 탈취되었다고 가정하면, 공격자는 토큰이 만료될 때 까지 서버에 요청을 할 수 있다.
토큰 인증 방식의 단점을 보완하기 위해 토큰의 타입을 리프레시 토큰과 엑세스 토큰으로 나누어 사용하는 방식의 JWT 토큰을 사용하게 된다.

JWT

JSON Web Token은 인증 헤더 내 사용되는 토큰 포멧이다. 토큰은 base64로 인코딩한 string으로 이루어진다. 토큰은 두 개의 시스템끼리 안전한 방법으로 통신할 수 있도록 설계하는 것을 도와준다.

  • JWT 장점

    • 계정 서버와 API 서버가 분리되어 있을 때 API 서버가 계정 서버에게 토큰의 유효성 여부를 물어보지 않고도 스스로 판단할 수 있다는 것이다.
    • Access Token은 단순하게 자원에 접근하는 Access Token이 아니라, 권한/ 인증에 대한 Token을 말한다.
    • Refresh TokenAccess Token과 똑같은 형태의 JWT이며 Access Token의 탈취 문제를 해결하기 위해 발급하는 토큰이다.
    • 처음의 로그인을 완료할 때 Access Token과 함께 발급되는 Refresh Token은 긴 유효시간을 가지면서 Access Token이 만료되었을 때 새로 발급해주는 열쇠가 된다.
    • JWT
  • JWT 특징
    세션/ 쿠키는 별도 저장소의 관리가 필요하지만, JWT는 서버 입장에서 요청을 받았을 때 발급한 후 검증만 하기 때문에 추가로 저장소가 필요 없다.

    • A 서버로 접속하였다가 B 서버로 요청한다 해도 확장성에 문제가 없다.
    • 토큰 기반으로 하는 다른 인증 시스템에 접근이 가능하다.

토큰과 세션의 차이

stateful 서버는 클라이언트에게 요청을 받을 때 마다 클라이언트의 상태를 계속해서 유지하고 이 정보를 서비스 제공에 이용한다.

그 예로는 세션을 유지하는 웹 서버가 있다. 로그인을 하면 세션에 로그인이 되었다고 저장을 하고 서비스를 제공할 때 해당 데이터를 사용한다. 세션은 서버의 메모리 또는 데이터베이스에 저장한다.

stateless 서버는 상태를 유지하지 않는다. 서버는 클라이언트 측에서 들어오는 요청만으로 작업을 처리한다. 클라이언트와 서버의 연결고리가 없기 때문에 서버의 확장성이 높아진다.
Client가 고유 식별자를 가지고, 해당 식별자를 바탕으로 인증을 처리한다는 점에서 두 기술은 같다.

세션이 식별자에 대한 정보를 서버에 저장한다고 하지만 결국 식별자의 일부는 Client에 저장한다. 보통 cookie로 저장.

세션은 그 식별자가 HTTP session에 한정된다는 점에서 토큰보다 제한된 범위의 활용성을 가진다.

큰 흐름에서 세션은 기존의 웹 서비스에서 HTTP session을 기준으로 정보를 처리하는것에 사용이 되었고, 토큰은 고유 식별자로 토큰을 만들어서 Client에 전달하는 방향으로 진화하였기에 토큰만 전달이 되었다면 다양한 포멧(json, xml) 구분없이 상태와 상관없이 stateless 폭 넓게 사용이 될 수 있다. 이것은 토큰 인증방식이 모바일 생태계에 맞는 인증방법이었고 활발하게 확산이 될 수 있는 이유이다.

그러므로, 새로운 서비스를 계획한다면 토큰 기반의 인증 방식이 더 나은 판단이 될 가능성이 높다.

세션 방식은 해당 서비스가 100% 모바일에 사용될 일이 없다면 선택하여도 된다.

적용 프로젝트

'Network' 카테고리의 다른 글

TLS, SSL과 HTTPS  (0) 2020.12.19
Web Server가 하는 일  (0) 2020.11.23
Web Server란?  (0) 2020.11.23
Web이란?  (0) 2020.11.23
Comments