JWT는 출입증이다

이동규 (Justin)·2025년 3월 8일

이것 뭐에요~?

목록 보기
3/3
post-thumbnail

JWT는 웹 상에서 '출입증' 역할을 한다.

어떤 클라이언트가 앱의 어떤 기능을 이용하고자 할 때,

  • JWT가 있는지 없는지
  • 가지고 있는 JWT가 위조되지 않은 진짜인지

확인하여 사용자를 인증하는 것(Authentication)이다. 여기에 JWT에 기록된 임의의 정보로 권한의 레벨을 조정할수도 있다(Authorization).

그런데 JWT는 그저 한줄의 문자열이다.

그렇다면 출입증과 같은 원리가 그저 한줄의 문자열로 어떻게 구현될 수 있을까?

먼저 JWT는 암호화 된, comma를 이용해 세 부분으로 이루어진 문자열이다.

Header.Payload.Signature

Header는 암호화에 사용된 알고리즘 등의 메타데이터를 포함,
Payload에는 사용자의 이름이나 권한 등의 정보,
Signature에는 앞의 두 내용을 비밀 키 로 서명한 내용이 포함된다.

그리고 이 JWT는 서버와 클라이언트라는 두 주체에 의해 이용된다. 바로 출입증 발급자와 출입증 사용자인 것이다.

JWT는 서버가 발급한다. 서버가 인증의 주체이고 클라이언트가 사용자인 것이다. 이해를 돕기 위해 회사 인사팀에서 사원에게 출입증을 발급해주는 상황에 비유해보자.

출입증을 발급할 때는 회사 인사팀만이 가진 검증기계(=비밀키)로 출입증의 내용을 암호화해서 출입증에 새겨넣는다. 추후에 이 암호화 된 내용을 검증기계로 판독해서 출입증의 내용과 동일한 값이 나오면 이 출입증의 내용이 조작되지 않았음을 확인할 수 있다(=verification).

이렇게 어려운 과정을 통해 발급된 출입증을 가진 사원이 출입구에 들어가며 출입증을 찍으면, 출입구에서는 방금 이야기한 방법을 사용해 출입증의 위조여부를 확인한다. 이러한 과정이 어떻게 문자열로 이루어지는지 아래 코드를 보자.

nodejs의 jsonwebtoken 라이브러리에서는 다음과 같은 코드로 JWT를 발급하고 verify 한다.

const jwt = require('jsonwebtoken');

// 비밀키는 외부유출을 막기 위해 보통 환경변수로 관리된다.
// 비밀키는 사용자가 임의로 작성할 수 있지만 난수로 작성되는 것이 좋다.
const secretKey = 'thisissecretkeythatyouneverknow'; 

const payload = { name: 'Justin' };

const token = jwt.sign(payload, secretKey);

이렇게 생성된 토큰을 클라이언트에게 보내주고,

// authorization header에 `Bearer <token>` 으로 담겨왔을 경우
const token = req.headers['authorization']?.split(' ')[1];

const decodedPayload = jwt.verify(token, secretKey)

이렇게 verification 할 수 있다.

출입증(토큰)을 어디에 저장해야 안전할까?

1. 로컬 스토리지

2. 세션 스토리지

3. 쿠키

profile
Visual Programming is in Progress..

0개의 댓글