Json 포맷을 이용해서 사용자의 속성을 저장하는 Claim 기반의 Web 토큰이다.
쉽게 말하면, 정보를 비밀리에 전달하거나 인증이 필요할 때 주로 사용하는 토큰인 것이다.
필요한 정보를 자체적으로 지니는 Self-Contained 방식으로 정보를 안정성 있게 전달한다.
JWT는 헤더(header), 페이로드(payload), 서명(signature)으로 구성되어 있다.


위의 Json 형태인 각 부분은 Base64로 인코딩 되어 표현되며, 각 부분은 . 구분자로 구분된다.
여기서 Base64라는 건 암호화된 문자열을 반환하는 게 아니라, 같은 문자열에 대해 항상 같은 인코딩 문자열을 반환한다고 한다.
토큰의 헤더에는 typ와 alg가 있다고 한다.
alg는 Signature 부분을 해싱하기 위한 알고리즘을 지정하는 것이다.
{
"alg": "HS256",
"typ": JWT
}
typ는 토큰 타입 / alg는 알고리즘 방식이며, HS255이나 RSA를 사용한다.
즉, 어떤 알고리즘을 암호화 할 것이며, 어떤 토큰을 사용할 것인지에 대한 정보가 담겨있다.
페이로드는 토큰에서 사용할 정보의 Claim이 담겨 있다고 한다.
수정이 가능하며, 필요한 정보를 추가할 수가 있다.
하지만 수정과 노출이 가능한만큼 인증에 필요한 정보만 담도록 해야한다!
비밀번호 등의 개인정보가 들어가면 노출될 위험이 있기에 토큰 발급일, 만료일 등의 정보만 담는 것이 좋다고 한다.
(페이로드의 Claim은 3가지로 나눈다고 하는데... jwt를 더 공부하면서 보충할 예정이다😂😉)
가장 중요한 부분에 해당하는 서명은!
토큰을 인코딩하거나 유효성 검증을 할 때 사용하는 고유한 암호화 코드다.
Signature 생성 과정
헤더와 페이로드의 값을 Base64로 인코딩 한 뒤,
비밀키를 이용해 인코딩한 값을 헤더의 알고리즘으로 해싱한다.
이후 해싱한 값을 다시 Base64로 인코딩하여 생성한 것이 서명이다!
위의 과정을 통해 Signature에는 헤더와 페이로드의 정보가 담기게 된다.
따라서, 누군가 payload에 조작된 정보를 넣더라도 Signature에 이미 기존의 payload값의 암호화 결과가 저장되어
이를 통해 조작여부를 판단할 수 있게 된다.

위의 이미지처럼 흘러간다고 보면 된다.
세부적으로 설명해보면...(*순서는 아래에서 새로 부여했다!)
1. 사용자가 로그인을 시도해서 ID와 비밀번호를 서버에 전송한다.
2. 서버는 해당 정보를 DB와 비교한 뒤, 유효한 경우 JWT 토큰을 생성한다.
이 때, 토큰은 주로 Access와 Refresh 2가지를 생성하는데,
Access는 당장 사용하는 용으로 보통 만료기간을 하루 정도로 짧게 잡는다고 한다.
Refresh는 Access가 만료되었을 때의 대체용으로 15일~1달까지도 길게 잡는다.
그리고 해당 토큰에는 사용자 ID나 권한, 만료 시간 등의 정보를 포함하여 생성한다.
3. 생성한 토큰을 사용자에게 전송해주면, 사용자는 API 요청 시 헤더에 담아 실행하게 된다.
4. 인증이 필요한 API마다 서버는 헤더에 담긴 토큰의 유효성 및 인증을 통해 필요한 응답을 전송한다.
🚨만약, Access 토큰이 만료되었다면?!?
1. 서버는 Refresh 토큰을 요청하여 전달받은 Refresh 토큰으로 검증을 한다.
2. Refresh 토큰이 검증에 성공할 경우, 이에 담긴 정보를 기반으로 Access 토큰을 새로 발급한다.
2-1. Refresh 토큰 마저 만료되거나 실패할 경우, 보통 로그인 화면으로 이동하게 구성을 한다.
사실 로그인을 구현하는 부분에 대해서
처음 배울 때는 Cookie와 Session만을 이용하다 실무를 하면서 JWT를 접하게 되었다.
다음 글에서 기존에 알던 방식과 JWT의 차이 등을 정리해보려고 한다!🫡