'페스타고' 프로젝트를 진행하며 JWT를 활용할 일이 생겼다.
JWT란?
JSON Web Token)는 JSON 형식의 데이터를 담은 토큰이다.
JWT는 주로 웹 어플리케이션에서 사용자의 인증 및 인가를 처리할 때 사용된다.
JWT의 구성요소에 대해 알아보자.
JWT 구성요소
JWT는 크게 아래 세 가지 요소로 구성된다.
- Header
- Payload
- Signature
각 구성요소들은 .
으로 구분된다.
xxxxxx.yyyyyy.zzzzzz
각 구성요소별 특징을 알아보도록 하자.
Header
헤더는 토큰의 유형, 암호화 알고리즘과 같은 토큰의 메타데이터를 포함한다.
헤더는 base64로 인코딩되어 있다.
{
"alg": "HS246",
"typ": "JWT"
}
- alg (암호화 알고리즘)
- JWT 토큰의 시그니처를 생성/검증하는데 사용하는 암호화 알고리즘을 지정한다.
- 일반적으로, HS256(대칭) / RS256(비대칭) 알고리즘을 사용한다.
- typ (토큰의 유형)
- 토큰의 유형을 지정한다. JWT의 경우 “JWT”로 설정한다.
- typ 필드에 “JWT”가 아닌 다른 값을 포함할 수도 있다. 예를 들어, 특정 도메인에서 사용자 정의 토큰 형식을 정의할 경우 typ의 값으로 해당 유형의 이름이 들어올 수 있다. (ex. “typ”: “MyCustomToken”)
Payload
페이로드는 토큰에 포함될 클레임(Claim)정보들을 포함한다.
클레임은 name-value 형태를 하는 정보의 ‘조각’들이다.
페이로드는 base64로 인코딩되어 있다.
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
클레임은 크게 세 가지 유형이 존재한다.
등록된 클레임 (Registered Claim)
표준적으로 정의된 클레임이다. 이는 서비스상 정보가 아닌, 토큰 자체의 정보를 담기 위해 이름이 미리 정의된 클레임들을 뜻한다.
모두 Optional하며, 필수적으로 포함되어야 하는 정보가 아니다.
name | 설명 | |
iss | issuer | 토큰 발급자 |
sub | subject | 토큰 제목 |
aud | audience | 토큰 대상자 |
exp | expiration time | 토큰 만료 시간 |
nbf | not before | 토큰 활성 날짜 (이 날짜 이전의 토큰은 활성화되지 않음을 보장) |
iat | issued at | 토큰 발급 시간 |
jti | jwt id | 토큰의 고유 식별자 (issuer가 여러명일 때 구분하기 위함) |
공개 클레임 (Public Claim)
사용자가 자유롭게 정의할 수 있는 클레임 정보들이다.
이들은 충돌 방지된 이름을 가지고 있어야 한다.
충돌 방지를 위해 IANA JSON Web Token Registry에 정의된 이름을 사용하거나, 이름을 URI 형식으로 짓는다.
{
"https://festa-go.co.kr/tickets": true
}
비공개 클레임 (Private Claim)
등록된 클레임도 아니고, 공개 클레임도 아닌 클레임을 뜻한다.
이는 주로 [클라이언트 ↔ 서버]간의 협의하에 이름을 정의하고 사용한다.
공개 클레임과 달리, 이름이 중복될 수 있으므로 주의해야한다.
{
"tokenType": "accessToken",
"ticketId": 3
}
Signature
시그니처는 토큰의 유효성을 검증할 때 사용하는 고유한 암호화 코드이다.
시그니처는 아래와 같은 과정을 통해 생성된다.
- Header와 Payload 값을 각각 Base64로 인코딩 하고
.
을 중간자로 합친다. - 인코딩한 값을 Header에 정의된 암호화 알고리즘으로 해싱한다. (이 때, 시크릿키가 사용된다.)
- 해싱된 값을 다시 Base64로 인코딩한다.
아래는 위 과정의 수도코드이다.
base64UrlEncode(
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secretKey)
)
)
유효성 검사
이렇게 암호화된 시그니처를 Base64UrlEncode(header).base64UrlEncode(payload)
와 비교해 같으면 유효한 토큰으로 판단하여 인증을 허용한다.
참고 자료
'프로그래밍' 카테고리의 다른 글
[Docker / MySQL] Docker로 띄운 mySQL 컨테이너에 employee sample DB 적재하기 (2) | 2023.08.15 |
---|---|
Git-flow란? (1) | 2023.07.12 |
OAuth2.0 란? (2) | 2023.07.07 |
[소프트웨어 아키텍처] 계층형 아키텍처에서 헥사고날 아키텍처(Hexagonal Architecture)로 (1) | 2023.05.22 |
[소프트웨어 아키텍처] 레이어드 아키텍처(Layered Architecture)란? (5) | 2023.04.25 |