캡스톤 프로젝트에서 유저의 로그인을 JWT를 통해 validation 하는 것을 구현한 적이 있다. 프로젝트를 리팩토링 하던 중 이부분에 대해서 개선할 방법은 없을까 하는 마음에 JWT에 대해 정리해보고자 하였다. 다행히 JWT 공식 홈페이지에 이에 대해 잘 정리가 되어있어서 이를 번역하고 추가로 조사한 것들을 정리해보았다.
JWT 란
JSON Web Token(JWT)는 당사자들 사이에서 정보를 JSON 객체로 안전하고 전송하기 위한 작고 독립적인 토큰 기반인증이다.
구조
xxxxx.yyyyy.zzzzz
Header
Header는 사용된 해시 암호화 알고리즘과 JWT라는 것을 알리는 Type 부분으로 이루어져 있다.
{
"alg" : "HS256",
"typ" : "JWT"
}
Payload
Claim 들을 담고 있는 곳이다. Claim은 사용자에 대한 프로퍼티나 속성이나 추가적인 데이터를 의미한다.
JWT는 쉽게 복호화 할 수 있기 때문에 민감한 정보는 피해야 한다.
데이터의 용량을 최대한 줄여야 한다.
Payload에는 세가지 Claim이 담겨있다.
Registered claims
필수는 아니지만 상호운용가능한 Claim set을 제공하기위해 권장되는 미리 정의된 Claim
- 발행자 (iss : Issuer)
- 만료 시간 (exp : Expireation time)
- 제목 (sub : Subject)
- 발행 시간 (ist : Issued At)
- 효과 발생 시간 (nbf : Not Before)
- JWT ID (jti : JWT ID)
Public claims
사용자가 원하는 대로 claim이 설정이 가능하다. 하지만 충돌을 피하기 위해 https://www.iana.org/assignments/jwt/jwt.xhtml에 있는 naming 규칙을 따라야한다. 이름 및 이메일과 같은 일반정보가 포함된다.
Private claims
Public claims와 비슷하지만 직원 ID 및 부서 이름과 같은 더 구체적인 정보가 포함된다.
{
"sub": "1234567890",
"name": "SonMinSang",
"admin": true
}
Signature
Header 와 Payload 값을 Header에 있는 해시 알고리즘을 통해 암호화한 값이다.
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
장점
- 별도의 저장소가 필요없다.
- 데이터의 무결성을 확인할 수 있다.
- 토큰 기반으로 다른 로그인 시스템에 접근 및 권한 공유가 가능하다. (쿠키와 차이)
단점
- 클라이언트 측에서 토큰을 관리하기 때문에 토큰을 강제로 만료시키기 어렵다.
- 토큰내에 페이로드 값을 담고 있기 때문에 탈취되었을 경우 중요한 데이터가 탈취될 가능성도 있다.
Reference