RFC 7519 에 명세되어 있는 국제 표준으로써, 통신 양자간의 정보를 JSON 형식을 사용하여 안전하게 전송하기 위한 방법
JWT는 정보가 토큰 자체에 포함된 (Self-Contained) 클레임 (Claim) 기반 토큰이다.
여기서 Claim은 사용자에 대한 프로퍼티나 속성을 말한다.
JWT는 주로 회원 인증이나 정보 전달에 사용된다.
토큰은 헤더(Header), 페이로드(Payload), 서명(Signature) 세 부분으로 이루어지며
각 구역은 . 기호로 구분된다.
xxxxx.yyyyy.zzzzz
헤더는 typ과 alg 두 가지 정보로 구성된다
{
"alg": "HS256",
"typ": "JWT"
}
페이로드는 토큰에서 사용할 정보로 구성된다. 정보의 한 조각을 클레임(Claim)이라 하고, Json(key/value) 형태로 이뤄져 다수의 정보를 넣을 수 있다.
클레임은 크게 3가지 종류로 나누어진다.
등록된 클레임 (Registered Claim)
미리 정의된 클레임. 등록된 클레임은 모두 선택적이다.
공개 클레임 (Public Claim)
사용자가 정의할 수 있는 클레임. 공개용 정보 전달을 위해 사용한다. 충돌을 방지하기 위해서는 클레임 이름을 URI 형식으로 짓는다.
비공개 클레임 (Private Claim)
해당 당사자들 간에 정보를 공유하기 위해 만들어진 사용자 지정 클레임. 이름이 중복되어 충돌이 될 수 있으니 사용할때에 유의해야합니다.
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
토큰을 인코딩하거나 유효성 검증을 할 때 사용하는 고유한 암호화 코드
헤더와 페이로드의 값을 각각 Base64로 인코딩하고, 인코딩한 값을 비밀키를 이용하여 헤더에서 정의한(alg) 알고리즘으로 해싱하고, 이 값을 다시 Base64로 인코딩하여 생성한다.
HMAC SHA256 을 사용한 서명 생성을 아래와 같은 수도코드 (pseudo-code) 로 나타낼 수 있다.
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
직접 JWT 토큰을 생성해 연습하고 싶다면, 아래 공식사이트에서 JWT 토큰을 쉽게 인코딩, 디코딩할 수 있다.
jwt.io Debugger
유효기간이 짧은 토큰을 발급하면 사용자는 로그인을 자주 해야해서 번거롭고, 유효기간이 긴 토큰을 발급하면 토큰을 탈취당해 보안이 취약해질 수 있다는 약점이 있다
.
이런 취약점을 막기 위해 Access Token과 Refresh Token을 함께 사용한다.
Access Token 이 만료되면, 클라이언트는 같이 발급된 Refresh Token 을 이용하여 서버에 Access Token 재발급을 요청한다.
이 방법 또한 Access Token 탈취의 위험이 있지만, 더 짧은 유효기간으로 그 가능성이 적다.
Refresh Token도 탈취될 가능성이 있기 때문에 유효기간을 적절히 설정해줘야 한다.
장점 | 단점 | |
---|---|---|
Cookie & Session | Cookie만 사용하는 방식보다 보안 향상 서버 쪽에서 Session 통제 가능 네트워크 부하 낮음 | 세션 저장소 사용으로 인한 서버 부하 |
JWT | 인증을 위한 별도의 저장소가 필요 없음 별도의 I/O 작업 없는 빠른 인증 처리 확장성이 우수함 | 토큰의 길이가 늘어날수록 네트워크 부하 특정 토큰을 강제로 만료시키기 어려움 |