Json Web Token
JWT
Json Web Token
- 사용자 인증 및 권한 부여에 널리 사용되는 토큰 기반 인증 방식이다.
- 클라이언트와 서버 간에 정보를 안전하게 전달하기 위한
JSON기반의 암호화된 토큰이다. - JWT는 세 파트로 나누어지며, 각 파트는 점(.)으로 구분하여 표현한다.
1) Header ( 헤더 ) : 해시 암호화 알고리즘과 토큰의 타입으로 구성
{
"alg": "HS256",
"typ": "JWT"
}
- alg: 서명에 사용할 알고리즘 (예: HMAC SHA256)
- typ: 토큰의 타입, 일반적으로 “JWT”
2) Payload ( 페이로드 ) : 내용, 즉 토큰에 담을 클레임(claim) 정보를 포함
{
"sub": "user123",
"name": "홍길동",
"role": "USER",
"exp": 1717032200
}
-
실제 데이터(클레임)을 담고있는 부분 -
주요 클레임 :
- iss(issuer) : 발행자
- exp(expiration time) : 만료시간
- sub(subject) : 제목
- iat(issued At) : 발행 시간
- jti(JWT ID) : 토큰의 고유 식별자
- 사용자 정의 클레임 ( 예 : role , email 등..)
3) Signature ( 서명 ) : 서명
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)
- 서명은 토큰의 위변조 여부를 검증하는 데 사용됨
- 비밀 키(secret)를 사용해 생성
- 서명을 통해 서버는 Token이 변조되지 않았음을 확인할 수 있다.
JWT 동작 방식
- 클라이언트의 로그인 요청
- 로그인에 성공했다면 Header, Payload에
Secret Key를 사용하여 Signature를 만든다- 이후 Base64로 Encoding한다
- 일반적으로 Cookie에 담아 클라이언트에게 JWT를 발급한다.
- 발급받은 JWT를 저장 후 서버에 요청할 때
AuthorizationHeader에 JWT를 담아 보낸다 - 서버에서 JWT의 유효성 검사를 통해 통과한다면 인증에 성공하여 요청을 처리해준다.
- JWT 만료, 위변조 여부를 검사한다.
JWT의 유효성 검사
- A의 JWT를 B가 탈취
- B가 탈취한 JWT를 임의로 수정
- B가 수정한 JWT로 Server에 요청
- 서버는 Signature를 사용하여 유효성 검사(Signature 불일치)
- Header, Payload를 서버의 Secret Key값을 이용해 Signature를 다시 만들어 비교한다.
- 임의로 조작된 데이터를 판별할 수 있다.
JWT 장단점
- 장점
- Signature로 서버의 보안성이 증가한다.
- Token 자체가 필요한 정보(유저 및 검증 정보)들을 모두 가지고 있다.
- 서버는 인증 정보와 관련된 별도의 저장소를 사용하지 않는다.
- 서버의 수평 확장성(Scale Out)이 높아진다.
- Cookie가 없는 다른 환경에서도 인증/인가를 적용할 수 있다.
- DB를 조회하지 않아도 된다.
- 단점
- Payload는 암호화 된 것이 아니라 민감한 정보를 다루지 못한다.
- Token의 길이가 길어서 트래픽이 증가하면 네트워크에 부하가 증가한다.
- 클라이언트 측에서 Token을 관리하기 때문에 탈취당하면 대처하기 어렵다.
JWT vs Session
| 항목 | JWT (JSON Web Token) | Session (세션 기반 인증) |
|---|---|---|
| 저장 위치 | 클라이언트 (주로 브라우저의 LocalStorage나 Cookie) | 서버 (메모리, DB 등) |
| 서버 상태 | Stateless (무상태) | Stateful (서버가 상태를 기억함) |
| 확장성 | 높음 (서버 간 상태 공유 불필요) | 낮음 (분산 서버에서는 세션 공유 필요) |
| 속도 | 일반적으로 빠름 (DB 조회 없음) | 느릴 수 있음 (세션 조회 필요) |
| 무효화 | 어려움 (토큰 유효기간 동안 유효) | 쉬움 (서버에서 세션 삭제) |
| 보안 | 토큰이 탈취되면 만료 전까지 사용 가능 | 세션 ID 탈취 시 위험하지만 제어 가능 |
| 저장 용량 | 클라이언트에 모든 정보 포함 (무거울 수 있음) | 서버에 정보 저장, 클라이언트는 세션ID만 보관 |
| 권한/정보 포함 | 포함 가능 (ex. role, email 등) | 일반적으로 별도로 DB에서 조회 |
| 토큰 만료 처리 | 클라이언트 토큰 자체에 exp 내장 |
서버에서 세션 만료 시간 관리 |
| 사용 예 | 모바일/SPA/API 서버, 마이크로서비스 | 전통적인 웹 앱, 내부 시스템 |
JWT를 그럼 언제 사용할까?
- 마이크로서비스 아키텍처 또는 서버리스 환경
- API 서버 간 확장성이 중요할 때
- 모바일 앱 또는 SPA(Single Page Application)에서 인증을 처리할 때
- 세션 공유가 어려운 분산 시스템
Session은 언제?
- 보안이 더 중요하고 서버 제어가 쉬운 환경
- 사용자 수가 적고 단일 서버 또는 간단한 구조
- 서버에서 인증 정보를 쉽게 무효화하거나 추적해야 할 때
- 전통적인 웹 애플리케이션에서 로그인/로그아웃을 구현할 때
결론
| 상황 | 추천 방식 |
|---|---|
| 빠른 확장성과 API 중심의 서비스 | JWT |
| 간단한 시스템, 보안 중심 웹 서비스 | Session |
Token의 유형
- Access Token
- 사용자 인증 후 서버가 발급하는 유저 정보가 담긴 토큰이다.
- 유효 기간 동안 API나 리소스에 접근할 때 사용한다.
- Refresh Token
- Access Token은 보안을 위해 짧은 수명을 가진다
- Access Token이 만료된 경우 재발급 받기 위해 사용한다.
- 주로 데이터베이스에 유저 정보와 같이 저장한다.
Access Token, Refresh Token 인증
- 클라이언트의 로그인 요청
- 로그인에 성공했다면 Header, Payload에
Secret Key를 사용하여 Signature를 만든다. - 발급받은 JWT를 저장 후 서버에 요청할 때
AuthorizationHeader에 JWT(Access Token)를 담아 보낸다. - 서버에서 JWT의 유효성 검사를 통해 통과한다면 인증에 성공하여 요청을 처리해준다.
Access Token이 만료 되었다면Refresh Token으로 토큰 재발급을 요청한다.- 서버로부터
Access Token을 재발급 받는다.