Knowledge of Dev

JWT(JSON Web Token)

jwkane 2024. 5. 29. 23:39

1. JWT(JSON Web Token)의 기본 개념

- JSON 객체를 사용하여 두 당사자 사이에 정보를 안전하게 전송하기 위한 토큰이다

- 주로 인증 및 권한 부여 사용된다

- 토큰 자체에 필요한 모든 정보가 포함되어 있어 별도의 상태 저장이 필요하지 않다

 

2. 구조

JWT는 세 가지 주요 부분으로 구성된다.

 

각 부분은 점(.)으로 구분한다

헤더(Header). 페이로드(Payload). 서명(Signature)

 

예시

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. -> 헤더(Header)

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ. -> 페이로드(Payload)

SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c -> 서명(Signature)

 

 

2-1 헤더(Header)


- 토큰의 유형과 사용된 서명 알고리즘을 지정
- 주로 두 가지 필드 포함
alg: 서명에 사용된 해시 알고리즘 (예: HMAC SHA256, RSA)
typ: 토큰의 타입 (보통 "JWT")

 

{
    "alg": "HS256",
    "typ": "JWT"
}

 

 

2-2 페이로드(Payload):



- 토큰에 포함될 클레임(Claim)들을 담고 있음

- 클레임은 엔티티(보통 사용자)와 추가 메타데이터에 대한 정보를 포함

{
    "sub": "1234567890",
    "name": "John Doe",
    "iat": 1516239022
}

# 클레임의 유형

 

등록된 클레임(Registered Claims)

- 예약된 클레임

- 사전에 정의된 이름을 사용 (예: iss, exp, sub, aud)


공개 클레임(Public Claims): 

- 사용자 정의 클레임

- 충돌을 방지하기 위해 이름 공간을 정의


비공개 클레임(Private Claims): 

- 특정 응용 프로그램 간에 사용하기 위해 정의된 클레임

 

 

2-3 서명(Signature)


- 헤더와 페이로드를 결합하고, 지정된 알고리즘과 비밀 키를 사용하여 생성됨
- 서명을 통해 토큰의 무결성과 진위 여부를 확인 가능

 

3. 작동 원리

 

토큰 생성


- 사용자가 로그인하면 서버는 사용자 정보를 기반으로 JWT를 생성

- 생성된 토큰을 클라이언트에게 전달

 

토큰 저장


- 클라이언트는 받은 JWT를 저장

- 보통 로컬 스토리지나 세션 스토리지에 저장

(쿠키에 저장할 수도 있지만, 보안 설정 필요)

 

토큰 전송


- 클라이언트는 서버에 요청을 보낼 때, JWT를 HTTP 헤더의 Authorization 필드에 포함시켜 전송

 

토큰 검증


- 서버는 요청을 받을 때, 토큰의 서명을 검증하여 토큰이 변조되지 않았는지 확인

서명이 유효하다면, 토큰의 페이로드에서 사용자 정보를 추출하고 요청 처리

 

4. 장, 단점

 

장점

 

Self-contained ( 자체적으로 필요한 정보 모두 포함 )


- 토큰 자체에 필요한 모든 정보를 포함하고 있기에
서버에 별도의 상태를 저장할 필요 없음

-> 서버의 부하 줄이고, 확장성 높임


보안

- 서명을 통해 토큰의 무결성과 진위 여부 확인

- 중요한 정보는 페이로드에 포함하지 않거나, 추가적으로 암호화 가능

 

(단, 중요한 정보를 포함할 경우,

반드시 암호화하여 전송해야 한다

JWT의 페이로드는 디코딩이 쉽기 때문에 누구나 읽을 수 있다 )


유연성


- 다양한 클레임을 포함할 수 있음

- 사용자 정보나 권한 데이터를 쉽게 확장 가능

 


확장성

 

여러 서버나 마이크로서비스 간에 사용자 정보를 공유할 때 유용

 


단점

 


크기

- JWT는 일반적으로 쿠키나 세션 ID보다 큼

-> 네트워크 오버헤드가 발생할 수 있음

 


JWT 탈취


- JWT는 만료되기 전까지 유효함

-> 서버가 토큰을 강제로 무효화 할 수 없음

이를 해결하기 위해 별도의 블랙리스트를 관리해야 할 수 있음

 

하지만

 

블랙리스트를 관리하게 되면

JWT의 장점이 상쇄되어

쿠키,세션 방법과 같은 검증절차가 추가되는 부분에 대해

고려해봐야 한다.

 

또 다른 방법으로는

리프레쉬 토큰(Refresh Token)을 발급하는 방법이 있다

 

 

# 리프레쉬 토큰(Refresh Token)의 작동 방식

 

초기인증


- 사용자는 사용자 이름 및 비밀번호을 사용하여 인증
- 서버는 인증이 확인되면 액세스 토큰(단기) 및 리프레쉬 토큰(장기)을 발급

 


리소스 액세스

- 클라이언트는 액세스 토큰을 사용하여 보호된 리소스에 액세스
- 액세스 토큰은 각 요청의 HTTP 헤더로 전송

 


토큰 만료 

- 수명이 짧은(일반적으로 15분~1시간) 액세스 토큰이 만료되면 

클라이언트는 리프레쉬 토큰을 사용하여 새 액세스 토큰을 얻음

 


토큰 새로 고침

- 클라이언트는 리프레쉬 토큰을 서버에 보냄
- 서버는 리프레쉬 토큰을 확인하고 유효한 경우 새 액세스 토큰(새로운 리프레쉬 토큰도 가능)을 발급

 


해지 및 보안

- 리프레쉬 토큰은 수동(예: 사용자 로그아웃) 또는 자동(예: 특정 기간 후)으로 만료될 수 있다
- 서버는 만료된 새로 고침 토큰을 사용할 수 없도록 블랙리스트 또는 만료된 토큰의 데이터베이스를 유지 관리한다.

 

 

오늘 배운 점

 

JWT란 무엇인지

어떤 구조 인지

장점과 단점에 대해 배웠다.

 

DB검증이 필요한 쿠키,세션 방식과 달리

 

DB까지 가서 검증하지않고

토큰 자체에 대한 검증만 되면 되기에

 

서버의 부하를 줄여줄 수 있다는 장점이 있다는 것을 알게되었고

 

토큰 검증 로직을

여러 서버나 마이크로서비스에서 활용하는 등

확장성이 있겠다고 생각했다.

 

시크릿 키를 활용한 서명 부분이 매우 중요하기에

시크릿 키를 구성, 보관에 굉장히 주의해야 한다는것과

 

페이로드 부분에 대한 디코딩은 쉽기 때문에필요한 최소한의 정보만 담아야 한다는 주의 사항도 배웠다.

 

토큰을 탈취 당했을 때 대응하는블랙리스트 관리, 리프레쉬 토큰 발급 등

 

관련 로직과실제로 적용되는 디테일한 과정에 대해 추가적인 공부를 해야겠다.