JWT(Json Web Token)
JWT(Json Web Token)는 JSON 포맷을 사용하여 정보를 안전하게 클라이언트와 서버 간에 교환하기 위한 토큰 기반 인증 방식이다. JWT는 사용자의 인증 및 데이터를 안전하게 주고받기 위해 널리 사용되는 기술로, 특히 RESTFul API와 같이 무상태(stateless) 아키텍처에서 많이 활용된다.
JWT는 클라이언트가 서버에 인증을 요청하고, 서버가 클라이언트에게 인증 토큰을 발급한 후, 이후 요청에서 이 토큰을 사용하여 인증 상태를 유지하는 방식으로 동작한다. 이를 통해 서버는 세션을 유지하지 않고도 사용자를 인증할 수 있다.
JWT의 구조
JWT는 세 가지 주요 파트로 구성되어 있으며, 점(.)으로 구분된다. 각각의 파트는 특정한 역할을 수행한다.
1. Header(헤더)
헤더는 토큰의 메타데이터를 담고 있다. 주로 사용된 알고리즘(예: HS256, RS256)과 토큰 타입 (예 : JWT)을 명시한다.
예시
{
"alg":"HS256",
"typ":"JWT"
}
2.Payload(페이로드)
페이로드는 실제 데이터가 담기는 부분으로, 주로 클레임(Claims) 이라고 불리는 정보를 포함한다. 클레임에는 사용자 식별 정보, 권한 정보, 토큰의 유효 기간 등이 포함된다.
클레임의 종류는 다음과 같다.
- 등록된 클레임(Registered Claims) : iss(발급자), exp(만료 시간), sub(주제)등
- 공개 클레임(Public Claims) : 사용자 정의 데이터로, 충돌 방지를 위해 URI 형식을 사용하는것이 권장된다.
- 비공개 클레임(Private Claims) : 클라이언트와 서버 간에 합의된 데이터
예시
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
3. Signature(서명)
서명은 토큰의 무결성을 검증하기 위해 사용된다. Header와 Payload를 결합한 후, 비밀 키를 사용하여 암호화된 해시를 생성한다. 이를 통해 데이터가 변조되지 않았음을 확인할 수 있다.
생성 방식
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)
이 세 부분은 각각 Base64Url로 인코딩되며, 최종적으로 Header.Payload.Signature 형태의 문자로 결합된다.
JWT의 동작 방식
JWT는 주로 다음과 같은 절차로 동작한다.
- 클라이언트 인증 요청 : 사용자가 로그인 시 아이디와 비밀번호를 서버에 전달한다.
- 서버에서 인증 확인 및 JWT 발급 : 서버느 사용자를 인증하고, 인증된 정보를 바탕으로 JWT를 생성하여 클라이언트에게 반환한다.
- 클라이언트의 JWT 저장 : 클라이언트는 받은 JWT를 브라우저의 로컬 스트리지 또는 쿠키에 저장한다.
- 클라이언트의 요청 시 JWT 전송 : 클라이언트는 API요청 시 JWT를 Authorization 헤더에 포함시켜 전송한다.
ex) "Authorization: Bearer <JWT>" - 서버에서 JWT 검증 및 요청 처리 : 서버는 JWT의 Signature를 확인하여 데이터가 변조되지 않았는지 확인하고, 유효한 토큰이면 요청을 처리한다.
JWT의 장점
- 자급적(Self-contained) 데이터: JWT는 사용자 정보를 자체적으로 포함하고 있어, 서버에서 별도의 세션 저장소를 유지할 필요가 없다. 이를 통해 서버 부하를 줄이고 성능을 개선할 수 있다.
- 확장성: RESTful API와 같은 무상태 아키텍처에서 유용하다. 여러 서버에 걸쳐 인증 상태를 쉽게 유지할 수 있어 분산 시스템에서도 효과적이다.
- 유연성: JWT는 사용자 정보뿐만 아니라 다양한 데이터를 포함할 수 있다. 예를 들어, 권한 정보(role), 만료 시간(exp), 사용자 설정 등이 가능하다.
- 보안성: 서명을 통해 데이터의 무결성을 보장하며, HTTPS와 함께 사용하면 데이터 탈취 위험을 줄일 수 있다.
JWT의 단점 및 주의점
- 토큰 크기: JWT는 자체적으로 데이터를 포함하므로, 세션 ID만 저장하는 방식보다 데이터 크기가 크다. 이는 대역폭 소모를 증가시킬 수 있다.
- 토큰 탈취 위험: 클라이언트 측에 저장된 JWT가 탈취되면, 만료 시간 전까지 권한이 악용될 수 있다. 이를 방지하려면 HTTPS를 반드시 사용하고, 토큰의 만료 시간을 짧게 설정하는 것이 중요하다.
- 토큰 무효화의 어려움: JWT는 서버에서 상태를 유지하지 않으므로, 로그아웃 시 토큰을 무효화하기 어렵다. 이를 해결하기 위해 블랙리스트를 사용하거나 짧은 만료 시간을 설정하여 주기적으로 토큰을 갱신하는 방식이 필요하다.
JWT와 세션 기반 인증 비교
| 항목 | JWT 기반 인증 | 세션 기반 인증 |
| 저장 위치 | 클라이언트 | 서버 |
| 스케일링 | 서버 부담 적음 | 서버 확장이 복잡 |
| 토큰 무효화 | 어려움 | 쉬움 |
| 보안 | HTTPS 필수 | 서버 관리 |
JWT를 안전하게 사용하는 방법
- HTTPS 사용: JWT는 민감한 정보를 포함할 수 있으므로, 반드시 HTTPS를 사용하여 네트워크를 통해 전송되는 데이터를 암호화해야 한다.
- 짧은 만료 시간 설정: 토큰의 exp(만료 시간)를 짧게 설정하여 탈취 시 악용 가능 시간을 최소화한다.
- 리프레시 토큰 사용: 짧은 수명의 액세스 토큰과 별도로 긴 수명의 리프레시 토큰을 사용하여 보안성과 사용자 경험을 모두 충족시킨다.
- 토큰 저장 위치 고려: XSS 공격 방지를 위해 로컬 스토리지 대신 HTTP-only 쿠키를 사용하는 것이 권장된다.
- 서명 키 관리: 서명에 사용되는 비밀 키는 안전하게 관리해야 하며, 주기적으로 키를 교체하는 것이 좋다.
JWT는 무상태 인증을 지원하며, 확장성과 유연성이 뛰어난 인증 및 데이터 교환 기술이다. 하지만 보안과 관련된 단점이 존재하므로, 이를 보완하기 위한 적절한 방법을 함께 생각해야한다. 환경에 맞게 JWT를 잘 활용하면 효율적이고 안전한 시스템을 구축할 수 있다.
'TIL(Today I Learned)' 카테고리의 다른 글
| 2024.12.24 Today I Learned (0) | 2024.12.23 |
|---|---|
| 2024.12.23 Today I Learned (0) | 2024.12.23 |
| 2024.12.17 Today I Learned (3) | 2024.12.17 |
| 2024.10.13 Today I Learned (1) | 2024.10.13 |
| 2024.09.25 Today I Learned (0) | 2024.09.25 |