1. JWT (JSON Web Token)
JWT 는 서로 다른 컴포넌트 간에 데이터를 전달하기 위해서 사용되는 토큰이다. JSON 형식의 객체를 암호화한 값들을 특정한 형식으로 구성한 문자열 형태를 띄고 있으며, 주로 웹서비스의 인증, 인가에서 세션과 쿠키의 대체제로 사용된다. JWT 의 JSON 객체는 name-value 쌍으로 구성되어 값을 저장한다.
토큰은 세션과는 달리 서버가 아닌 클라이언트에 저장된다. 이때문에 서버에서 메모리나 스토리지 등을 위해 세션을 관리했던 서버의 부담을 덜 수 있다. 그렇기 때문에 분산 시스템과 같이 여러 request / reply 가 발생하는 구조의 시스템에서 많이 사용한다.
2. JWT 구조
JWT 는 세가지 부분으로 구성되는데, header, payload 그리고 signature 이다. Header 와 payload 는 Base64Url 로 인코딩된 string 으로 표현되는데, 마침표로 연결되어 JWT 를 구성한다. 해당 JWT 는 사용되는 알고리즘에 따라서 public key 또는 secret key 로 서명된다. 이를 표현하면 다음과 같다.
- JWT 형식: xxxxx.yyyyy.zzzzz
여기서 xxxxx 가 header, yyyyy 가 payload 그리고 zzzzz 가 signature 를 의미한다.
header, payload, signature 의 각 내용은 다음과 같다.
- header
JWT 은 token 의 타입과 HMAC SHA256 또는 RSA 와 같은 서명 알고리즘으로 구성되어 있다.
{
"alg": "HS256",
"typ": "JWT"
}
header 를 JSON 으로 표현하면 위와 같다. 이러한 값이 Base64Url 로 암호화 되어서 JWT 에 표현된다.
- payload
payload 는 JWT 의 정보 조각들, claim 들을 포함하는 부분이다. claim 은 사용자나 추가적인 정보들을 표현한다. claim 은 registered, public 그리고 private 의 3가지 종류로 구분된다.
1) registered claim
registered claims 는 미리 정의가 되어있는 claim 들로 필수요소는 아니지만 일반적으로 필요한 추천 요소들이다. 요소들은 다음과 같다.
- iss (issuer): 토큰 발급자
- sub (subject): 토큰의 제목
- aud (audience): 토큰의 타겟, 대상자
- exp (expiration time): 토큰의 만료기간
- nbf (not before): 토큰이 유효해지는 시간으로 해당 시간이 되기 전까지는 토큰을 사용한 요청이 수행되지 않는다.
- iat (issued at): 토큰이 발행된 시간
- jti (JWT id): 토큰의 unique id
대표적으로 iss (issuer), exp (expiration time), sub (subject), aud (audience) 등이 있다.
2) public claim
claim 은 사용자가 직접 name 을 정의하여 값을 저장할 수 있다. 하지만 이 중에서 여러 claim 들의 이름이 중복되어 충돌하는 것을 방지하기 위해서 IANA 의 JSON Web Token Claims 에 등록하여 claim 을 사용할 수 있다. 이러한 claim 들을 public claims 이라고 부른다.
3) private claim
따로 등록되거나 공개된 claim 이 아닌 사용자 간에 협의하여 사용하는 claim 들을 의미한다. 다른 claim 들과 충돌할 수 있기 때문에 잘 유의하여 사용해야 한다.
- signature
header, payload 를 Base64 URL-safe encode 한 이후 header 에 명시 된 해시 함수를 적용하고, 개인키로 서명한 전자서명이 담겨있다. 이를 표현하면 다음과 같다.
Sig = HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
이 예제의 경우 HMAC SHA256 해시함수를 사용하여 서명을 암호화하였다. 이 전자서명을 통해서 header 와 payload 가 변조, 조작되었는지 확인하는데 사용된다. 이를 통해서 JWT 를 신뢰할 수 있는 지 확인한다.
3. JWT 적용 예시
JWT 는 주로 사용자 정보를 포함하도록 하여 서버 요청에서 사용자 인증과 인가에 많이 사용된다. 사용자가 웹앱에 로그인할 때 서버는 사용자의 정보 (이름, ID, 만료시간) 등을 포함하고 있는 JWT 를 발행한다. 이 JWT 를 클라이언트가 받아서 쿠키나 로컬 저장소에 저장한다.
이후, 로그인 한 사용자가 서버에 요청을 보낼 때 저장된 JWT 를 request header 의 authorization 에 추가하여 요청한다. 요청을 받은 서버는 JWT 를 디코딩하여 정보들을 검증하여 요청에 대한 사용자 인증과 인가를 수행한다.
JWT 는 요청에 대한 사용자의 인증, 인가에 필요한 정보들을 모두 가지고 있기 때문에 서버 측에는 따로 세션 저장소가 필요 없어진다. 이때문에 분산 시스템과 같이 컴포넌트간에 서로 많은 요청을 주고받는 구조에서 JWT 를 사용하면 가볍고 확장성이 좋은 인증 구조를 구축하도록 할 수 있다.
4. 장점
- stateless
JWT 는 따로 expire time 을 가지고 있고 그외에는 stateless 하기 때문에 서버에서 따로 세션 관리를 할 필요가 없다. 이때문에 확장성에 용이해서 분산시스템에서 많이 사용된다.
- portable
JWT 는 특정 플랫폼에 종속되지 않고 여러 도메인과 플랫폼에 적용할 수 있다. 이때문에 다양한 웹앱 솔루션에 적용할 수 있다.
- secure
JWT 는 보안 알고리즘을 통해서 서명되고 암호화 되기 때문에 변조 및 조작에 대항할 수 있다.
- standardized
JWT 는 개방형 표준을 기반으로 하기 때문에 기존 프로젝트 등에 쉽게 적용할 수 있다.
[Reference]
- https://www.rfc-editor.org/rfc/rfc7519
'기타 > Git' 카테고리의 다른 글
[git] git hooks / pre-commit (0) | 2023.02.03 |
---|---|
[git] git 브랜치 병합 전략 (merge, rebase) (0) | 2022.06.15 |
[git] git stash (0) | 2021.10.30 |
[git] squash로 commit 합치기 (0) | 2021.10.30 |
[git] git submodule / subtree (0) | 2021.10.19 |