WEB

[WEB] 토큰 기반 인증과 JWT

mhko411 2021. 10. 13. 17:45
728x90

프로젝트에서 로그인을 구현할 때 JWT를 많이 사용했다. 시간이 지날수록 JWT를 사용했던 이유와 동작 원리를 잊게되었다. 따라서 이번에는 토큰 기반 인증의 원리와 이러한 인증의 방법 중의 하나인 JWT를 정리해보려고 한다.


토큰 기반 인증

토큰 기반 인증은 로그인을 시도했을 때 서버에서 가입된 사용자인지 확인 후에 이미 가입된 사용자일 경우 사용자에게 토큰을 발급한다. 이때 토큰은 클라이언트측에서 관리를 하며 로그인이 필요한 서비스를 이용할 때 토큰을 함께 보내어 인증을 시도한다. 

 

세션 기반 인증의 문제점

토큰 기반 인증을 사용하게 된 이유를 기존의 세션 기반 인증의 문제점에서 찾아보자. 기본적으로 세션 기반 인증은 서버가 클라이언트에 대한 정보를 메모리/디스크/데이터베이스 등에 저장하여 세션을 유지한다.

 

세션 기반 인증을 사용하면 클라이언트의 인증을 서버에 저장해야 한다. 이에 대한 정보는 대부분 메모리에 저장하게 되는데 로그인한 사용자가 증가했을 때는 과부하가 발생한다. 이를 해결하기 위해 데이터베이스에 저장하기도 하지만 마찬가지로 사용자가 증가했을 때 성능이 저하될 수 있다.

 

또한, 서비스를 이용하는 사용자가 증가하여 서버를 확장하려고 했을 때 어려움이 따른다. 증가한 사용자의 트래픽을 수용하기 위해 여러 개의 프로세스를 실행시키거나 여러 대의 서버를 추가하는 과정이 복잡하다. 

 

토큰 기반 인증의 장점

위에서 알아본 세션 기반 인증의 문제점을 해결하기 위해 토큰 기반 인증이 나타났다. 토큰 기반 인증의 특징을 통해 토큰 기반 인증의 장점을 알아보자.

 

토큰 기반 인증은 서버와 클라이언트가 지속해서 연결을 유지하지 않는다. 이처럼 상태를 유지하지 않는 것을 stateless라고 한다. 따라서 세션 기반 인증에서 연결을 유지하기 위해 저장해야 했던 사용자의 정보를 저장하지 않아도 되기 때문에 메모리의 사용을 줄일 수 있다.

 

또한 세션 기반 인증의 경우 처음에 접속했던 서버와 세션이 생성되어 해당 서버에만 요청을 보낼 수 있다. 하지만 토큰을 사용한다면 어떠한 서버로 요청을 해도 상관이 없다. 왜냐하면 서버는 클라이언트의 토큰을 통해 인증을 하기 때문이다. 따라서 서버의 확장이 용이하다.

 

마지막으로 토큰 기반 인증은 유효한 토큰을 포함해서 서버에 요청하면 되기 때문에 여러 디바이스와 호환이 가능하며 다른 도메인에서도 요청이 정상적으로 처리된다.


JWT

JWT(Json Web Token)는 웹 표준(RFC 7519)이며 두 개체 사이를 JSON 객체를 사용하여 가볍고 안전하게 정보를 주고받을 수 있다. 또한 로그인 시스템에서 필요한 유저 정보 등을 JWT의 토큰에 포함되어 있으며 토큰이 검증되었다는 것을 증명하기위한 signature를 포함하고 있다.

 

JWT의 구조

JWT는  .  (점)을 통해 Header, Payload, Signature를 구분한다. 아래는 JWT의 예시이다.

ey0eXAiOiJKV1QiLCJhNiJ9.eyJ0b2tlbl90B0MjY5jJ9.p9PcxOBGSn8ZWfSpJtZA6Kxo

 

본인의 토큰을 아래의 사이트에서 입력하면 해석할 수 있다.

https://jwt.io/

 

JWT.IO

JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

jwt.io

 

Header

Header는 typ와 alg라는 두 가지 정보를 가지고 있다.

  • typ : 토큰의 타입을 명시하며 위의 사이트에서 확인하면 JWT가 명시되어 있을 것이다.
  • alg : 토큰을 검증할 때 사용하는 해싱 알고리즘을 지정한다. 
{
  "typ": "JWT",
  "alg": "HS256"
}

 

Payload

Payload에는 토큰에 담을 내용이 들어있다. Payload에 있는 속성들을 클레임 셋(Claim Set)이라 부르며 {key: value} 쌍으로 이루어져 있다. 클레임 셋은 토큰 생성자의 정보, 생성 일시, 유저 아이디 등이 담겨져 있다.

{
  "token_type": "access",
  "exp": 1634269361,
  "jti": "24f16a0b5bb730b0a56ddc2407",
  "user_id": 2
}

 

Signature

JWT의 마지막 부분에는 검증을 위한 Signature가 포함되어 있다. Header의 인코딩 값과, Payload의 인코딩 값을 합친 후 주어진 비밀키로 해쉬를 하여 생성한다.

'WEB' 카테고리의 다른 글

[Django 09] Authentication  (0) 2021.03.23
[Django 08] Forms  (0) 2021.03.16
[Django 07] CRUD  (0) 2021.03.11
[Django 06] Model  (0) 2021.03.10
[Django 05] form 사용하기  (0) 2021.03.09