[JWT] 1. 토큰(Token) 기반 인증

Bomin·2022년 9월 19일
0

[Side Project]

목록 보기
1/4
post-thumbnail

Token

토큰 기반 인증은 모던 웹서비스에서 많이 사용되고 있다.

API를 사용하는 웹서비스 개발한다면, 토큰을 사용하여 유저들의 인증 작업을 처리하는 것이 가장 좋다.

토큰 기반 인증 시스템을 선택하는 이유?

1. 서버의 확장성이 높다.

Stateful 서버

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

Stateless 서버

  • 클라이언트의 상태를 유지 하지 않는다.
  • 상태정보를 저장하지 않으면, 서버는 클라이언트측에서 들어오는 요청만으로만 작업을 처리한다.
  • 클라이언트와 서버의 연결고리가 없기 때문에 서버의 확장성(Scalability)이 높아진다.

2. 모바일 어플리케이션에 적합하다.

Android/ iOS 모바일 어플리케이션을 개발한다면, 안전한 API를 만들기 위해서는 쿠키 같은 인증시스템은 이상적이지 않다.(쿠키 컨테이너를 사용해야함).

토큰 기반 인증을 도입한다면, 간단하게 이 번거로움을 해결할 수 있다.

3. 인증정보를 다른 어플리케이션으로 전달 가능하다.

대표적인 예제로 OAuth 가 있다. 페이스북/구글 등의 소셜 계정들을 이용하여 다른 웹서비스에서도 로그인 가능하게 할 수 있다.

4. 보안을 높일 수 있다.

토큰 기반 인증 시스템을 사용하여 어플리케이션의 보안을 높일 수 있다.

단, 무조건 해킹의 위험에서 벗어나는 것은 아니다.

토큰을 왜 사용할까?

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

1. 서버 기반 인증

기존의 인증 시스템에서는 서버 측에서 유저들의 정보를 기억하고 있어야 한다.

이 세션을 유지하기 위해서는 여러가지 방법이 사용되는데 주로 메모리/디스크/데이터베이스 시스템에 담는다.

             🔽 서버 기반 인증 시스템의 흐름

이런 방식의 인증 시스템 아직 많이 사용되고 있긴하다.

하지만, 이런 방식의 인증 시스템은 문제점이 보이기 시작했다. 예를 들어 서버를 확장하기가 어려웠다.

2. 서버 기반 인증의 문제점

세션

유저가 인증을 할 때, 서버는 이 기록을 서버에 저장해야한다. 이를 세션이라고 부르고, 대부분의 경우 메모리에 이를 저장한다. 그런데 로그인 중인 유저의 수가 늘어난다면? 서버의 램이 과부화될 것이다. 이를 피하고자, 세션을 DB시스템에 저장하는 방식도 있지만, 이 또한 유저의 수가 많으면 DB 성능에 무리를 준다.

확장성

세션을 사용하면 서버를 확장하는 것이 어려워진다. 이 서버의 확장이란, 단순히 서버의 사양을 업그레이드 하는 것이 아니라, 더 많은 트래픽을 감당하기 위해 여러 개의 프로세스를 돌리거나, 여러대의 서버 컴퓨터를 추가하는 것을 의미한다. 세션을 사용하면서 분산된 시스템을 설계하는 것은 불가능하지는 않지만 과정이 매우 복잡해진다.

CORS(Cross-Origin Resource Sharing)

교차 출처 리소스 공유 (CORS) - HTTP | MDN

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

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

토큰 기반 시스템은 stateless 하다. 즉 무상태로 상태유지를 하지 않는다. 유저의 인증 정보를 서버나 세션에 담아두지 않는다.

이 개념 하나만으로 위에서 서술한 서버에서 유저의 인증 정보를 서버측에 담아줌으로서 발생하는 많은 문제점들이 해소된다.

세션이 없으니 유저들이 로그인 되어있는지 안되어있는지 신경 쓰지 않으면서 서버를 손쉽게 확장 할 수 이있다!

토큰 기반 시스템의 구현 방식은 시스템마다 크고작은 차이가 있겠지만, 대략적으로 보면 다음과 같다:

  1. 유저가 아이디와 비밀번호로 로그인한다.

  2. 서버 측에서 해당 계정정보를 검증한다.

  3. 계정정보가 정확하다면, 서버측에서 유저에게 signed 토큰을 발급해준다.

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

  4. 클라이언트 측에서 전달받은 토큰을 저장해두고, 서버에 요청(API 요청 등)을 할 때마다, 해당 토큰을 함께 서버에 전달한다.

  5. 서버는 토큰을 검증하고, 요청에 응답한다.

웹서버에서 토큰을 서버에 전달 할 때에는, HTTP 요청의 헤더에 토큰값을 포함시켜서 전달한다.

토큰의 장점

무상태(stateless) 이며 확장성(scalability)이 있다

토큰 기반 인증 시스템의 중요한 속성이다.

토큰은 클라이언트사이드에 저장하기 때문에 완전히 stateless 하며, 서버를 확장하기에 매우 적합한 환경을 제공한다. 만약 세션을 서버측에 저장하고 있고, 서버를 여러대를 사용하여 요청을 분산하였다면, 어떤 유저가 로그인 했을 땐, 그 유저는 처음 로그인했던 그 서버에만 요청을 보내도록 설정해야한다. 하지만 토큰을 사용한다면, 어떤 서비스로 요청이 들어가도 상관이 없다.

보안성

클라이언트가 서버에 요청을 보낼 때, 더 이상 쿠키를 전달하지 않기 때문에 쿠키 사용 시 발생하는 취약점이 사라진다. 하지만 토큰을 사용하는 환경에서도 취약점이 존재 할 수 있으니 대비해야한다.

Extensibility (확장성)

이 확장성은, Scalablity 와는 또 다른 개념이다.

Scalability는 서비스를 확장하는 것을 의미하고, Extensibility는 로그인 정보가 사용되는 분야를 확장하는 것을 의미한다. 토큰을 사용하여 다른 서비스에서도 권한을 공유할 수 있다.

즉 어떤 웹서비스에 Facebook, Naver, GitHub, Google 계정 등으로 로그인 할 수 있다는 것이다.

토큰 기반 시스템에서는 토큰에 선택적인 권한만 부여하여 발급을 할 수 있다. 예를 들어 어떤 웹서비스에서 네이버 계정으로 로그인 했다면, 프로필 정보를 가져오는 권한은 있어도, 포스트를 작성할 수 있는 권한은 없게 할 수 있다.

여러 플랫폼 및 도메인

어플리케이션의 서비스와 규모가 커지면, 여러 디바이스를 호환시키고 더 많은 종류의 서비스를 제공하게 된다. 토큰을 사용한다면, 그 어떤 디바이스,도메인에서도 토큰만 유효하다면 요청이 정상적으로 처리 된다. 서버 측에서 애플리케이션의 응답부분에 다음 헤더만 포함 시켜주면 된다.

Access-Control-Allow-Origin: *

이런 구조라면, assets 파일들(img,css,js,html 파일 등)은 모두 CDN(콘텐츠 전송 네트워크, 지리적으로 분산된 여러 개의 서버) 에서 제공하도록 하고, 서버 측에서는 오직 API만 다루도록 하게 설계할 수 있다.

웹 표준 기반

토큰 기반 인증 시스템의 구현체인 JWT는 웹 표준 RFC 7519 에 등록이 되어있다. 그러므로 여러 환경에서 지원이 되며 (.NET, Ruby, Java, Node.js, Python, PHP 등) 수많은 회사의 인프라스트럭쳐에서 사용 되고 있다 (구글, 마이크로소프트 등)

자료 참고
https://velopert.com/2350

profile
Frontend-developer

0개의 댓글