목표
JWT 정리
진행
JWT는 Json Web Token으로, Json 객체에 인증에 필요한 정보를 담아 비밀/공개/개인 키로 서명한 토큰이다.
JWT의 구조
JWT는 세 부분으로 구성된다.
```
HEADER.PAYLOAD.SIGNATURE
```
1. Header(헤더)
헤더는 토큰의 타입과 서명 알고리즘의 정보를 표시한다.
```json
{
"alg": "HS256",
"typ": "JWT"
}
```
- alg : 토큰 서명 알고리즘
- 토큰의 알고리즘은 RS256, HS256, PS256이 있고, Auth0 공식문서에서 자세히 다루고 있다.
- typ : 토큰의 타입
2. Payload(페이로드)
토큰에 포함된 청구(claim) 정보를 담고 있다. 이는 사용자 정보나 토큰의 유효 기간 등을 포함할 수 있다.
```json
{
"iss": "https://auth.example.com",
"sub": "1234567890",
"aud": "https://api.example.com",
"exp": 1622563200,
"iat": 1622556000,
"jti": "e9bc097a-7b4b-4b8b-87e2-543b43f7a0f9",
}
```
자주 사용되는 claim들을 넣은 페이로드이다.
- iss(Issuer) : 토큰 발급자를 식별할 수 있는 식별
- sub(Subject) : 토큰의 주체를 식별하는 고유 식별자 (쉽게 말해 토큰의 이름)
- aud(Audience) : 해당 토큰의 수신자
- exp(Expiration Time) : 토큰의 만료 시간
- iat(Issued At) : 토큰이 발급된 시간
- jti(JWT ID) : JWT의 고유 식별자
> 가장 흔하게 사용되는 claim이지만 모두 다 넣지 않아도 상관없다.
## 3. Signature(서명)
토큰의 무결성을 검증하기 위해 사용된다.
헤더와 페이로드를 인코딩한 후 비밀 키와 함께 서명 알고리즘을 적용하여 생성된다.
서명의 생성 과정은 다음과 같다.
1. 헤더와 페이로드 인코딩(각각 Base64Url로 인코딩)
2. 서명 생성
3. 서명 추가 : 생성된 서명을 JWT의 마지막 부분에 추가하여 최종 토큰을 완성한다.
```
header.payload.signature
```
### 서명 검증
서명 검증 과정은 다음을 따른다.
1. 헤더와 페이로드 디코딩
2. 서명 재생성 : 디코딩된 헤더와 페이로드를 통해 서명을 재생성한다.
3. 서명 비교
> JWT의 서명을 사용할 때에는 exp 클레임을 통해 토큰의 유효 기간을 설정하고, 만료된 토큰은 사용되지 않도록 하는 것이 안전하다.
# JWT 토큰의 사용 예시
## 사용자 인증
1. 사용자가 로그인 요청
2. 서버에서 사용자를 검증
3. 검증이 완료 됐다면 JWT를 생성 후 반환
4. 클라이언트에서 토큰 저장(로컬 스토리지 or 세션 스토리지)
만약 사용자가 인증이 필요한 리소스에 접근하게 된다면 클라이언트는 저장된 JWT를 헤더에 담아 서버에 보낸다.
```
GET /api
Authorization: Bearer "JWT토큰"
```
5. 서버에서 토큰 검증
-> 만약 유효한 토큰이라면 요청을 처리해준다.
## 정보 교환
JWT는 데이터의 무결성을 보장할 수 있기 때문에, 서버 간 정보를 안전하게 교환할 수 있다.
1. 주문 처리 서비스에서 JWT 생성
2. 결제 서비스로 요청 전송(JWT 토큰을 담아 API 요청을 보냄)
3. 결제 서비스에서 JWT 검증 후 데이터 처리
## API 접근 제어
1. 클라이언트가 API 게이트웨이에 요청(JWT 토큰을 담아 보냄)
2. API 게이트웨이에서 JWT 검증
3. 요청 라우팅(검증 성공 시)