인증(Authentication)과 인가(Authorization) 세션을 진행하면서, 인증과 인가의 절차와 인증의 필수요소인 패스워드 암호화, 인가의 필수 요소인 Json Web Token에 대해 알아보았다. 그에 더해 토큰 기반 인증 시스템의 특성과 JWT의 특징에 대해 찾아봤다.
토큰 기반 인증은 최근의 웹서비스에서 아주 많이 사용되고 있다. 토큰 기반 인증 시스템은 어떻게 작동되고, 무슨 장점을 가지고 있으며, 왜 나타나게 된걸까? 이를 이해하기 위해 먼저 기존의 서버 기반 시스템에 대해 알아보자.
기존의 서버 기반 인증 시스템은 서버측에서 유저들의 정보를 기억하고 있어야 했다. 따라서 여러가지 문제점이 발생했는데,
이런 문제점들을 해결하기 위해 토큰 기반 인증 시스템을 사용하기 시작했다.
Stateful Server의 경우 클라이언트에게 요청을 받을때마다 상태를 유지하고 정보를 서비스 제공에 이용한다. 반면 Stateless Server에서는 상태정보를 저장하지 않고, 서버는 클라이언트의 요청만으로 작업을 처리하며 세션을 사용하지 않는다. 따라서 토큰을 사용하면 클라이언트와 서버의 연결고리가 없어 서버를 확장하기에 매우 적합한 환경을 제공한다.
클라이언트가 서버에 요청을 보낼때 더이상 쿠키를 보내지 않으므로 취약점이 사라진다.
서버를 확장시키는 것 뿐 아니라 로그인 정보가 사용되는 분야를 확장할 수 있다. 우리가 Google 계정을 이용해 Notion, Slack등을 이용하는 것처럼 토큰에 선택적인 권한을 부여해서 발급할 수 있다.
대략적인 토큰 기반 인증 시스템의 구현 방식은 다음과 같다.
- 유저가 아이디와 비밀번호로 로그인을 한다.
- 서버측에서 해당 계정정보를 검증한다.
- 계정정보가 정확하다면, 서버측에서 유저에게 signed 토큰을 발급해준다.
- 클라이언트 측에서 전달받은 토큰을 저장해두고, 서버에 요청을 할 때 마다 해당 토큰을 함께 서버에 전달한다.
- 서버는 토큰을 검증하고, 요청에 응답한다.
이러한 토큰 기반 인증 시스템의 구현체가 바로 Json Web Token 이다.
JWT는 웹표준으로서 C, Java, Python 등 대부분의 주류 프로그래밍 언어에서 지원된다. 또한 필요한 모든 정보를 자체적으로 가지고 있어 자가 수용적(Self-contained)이며 그렇기에 두 개체 사이에서 쉽게 전달될 수 있는 장점들을 가지고 있다.
JWT는 .
으로 구분되는 Header, Payload, Signature의 3가지 문자열로 되어있다.
Header는 토큰의 타입과 해싱 알고리즘이라는 두가지 정보를 담고 있다.
{"alg":"HS256","typ":"JWT"}
보통 해싱 알고리즘은 HS256
을 사용하지만 HS512
을 이용해 토큰을 더 길게 만들수 있다.
Payload에는 토큰에 담을 정보가 들어가며, 담는 정보의 한 조각은 name/value의 한 쌍으로 이루어진 Claim이라고 부른다. Claim은 Registered, Public, Private의 세 분류로 나뉘어져 있다. Registered Claim은 토큰 발급자, 토큰 제목, 토큰 만료시간, 토큰 발급시간 등 토큰에 대한 정보를 담기 위해 이미 이름이 정해진 Claim 들이다.
JWT의 마지막 부분은 서명으로, Header의 인코딩값과 Payload의 인코딩값을 합친 후 주어진 비밀키로 해싱하여 생성한다.
Python에서 JWT를 사용하는 방법은 매우 간단한다.
import jwt
token = jwt.encode(data, SECRET_KEY, ALGORITHM)
위와 같이 JWT를 쓰기 위한 Library를 import하고, jwt.encod()
함수 안에 토큰에 담을 Data와 Signature를 만들기 위한 SECRET_KEY
, 그리고 해싱에 쓰일 알고리즘을 넣어주면 JWT를 발급할 수 있다!
참고링크
링크텍스트
🐼👍🏼🔥🌈☀️😊