JWT은 일반적으로 클라이언트와 서버, 서비스와 서비스 사이 통신시 권한 인가를 위해 인증에 필요한 정보들을 암호화시킨 토큰을 뜻한다. URL에 대해 안전한 문자열로 구성되어 있기 때문에 HTTP어디든 위치할 수 있다. 그래서 세션/쿠키 방식과 유사하게 사용자는 Access Token을 HTTP 헤더에 실어 서버로 보낼 수 있다. 주로 회원 인증이나 정보 전달에 사용된다.
토큰을 만들기 위해서는 크게 3가지 Header,Payload, Verify Signature으로 이루어지며, Json 형태인 각 부분은 Base64로 인코딩 되어 표현된다. Base64는 암호화된 문자열이 아니고, 같은 문자열에 대해 항상 같은 인코딩 문자열을 반환한다.
HEADER.PAYLOAD.SIGNATURE
토큰의 헤더는 typ와 alg 두가지 정보로 구성된다.
{
"alg": "HS256", // alg는 서명 시 사용하는 알고리즘
"typ": "JWT" // kid는 서명 시 사용하는 키(Public/Private Key)를 식별하는 값
}
위의 JSON객체를 문자열로 직렬화하고 UTF-8과 Base64 URL-Safe로 인코딩하면 아래처럼 해더가 생성된다.
Base64URLSafe(UTF-8('{"alg": "ES256","kid": "Key ID"}')) => eyJhbGciOiJFUzI1NiIsImtpZCI6IktleSBJRCJ9
토큰의 페이로드에는 토큰에서 사용할 정보의 조각들인 클레임(Claim)이 담겨있다. 클레임은 총 3가지로 나누어지며, JSON형태로 다수의 정보를 넣을 수 있다.
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
위와 같은 JSON 객체를 문자열로 직렬화하고 Base64 URL-Safe로 인코딩하면 다음과 같이 페이로드를 생성된다.
Base64URLSafe('{"sub": "1234567890","name": "John Doe","iat":"1516239022"}') => eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
토큰 정보를 표현하기 위해 이미 정해진 종류의 데이터들로 선택적으로 작성이 가능하면 사용할 것을 권장한다. 또 간결하게 하기위해 key는 모두 길이 3의 String이다.
iss: 토큰 발급자(issuer)
sub: 토큰 제목(subject)
aud: 토큰 대상자(audience)
exp: 토큰 만료 시간(expiration), NumericDate 형식으로 되어 있어야 함 ex) 1480849147370
nbf: 토큰 활성 날짜(not before), 이 날이 지나기 전의 토큰은 활성화되지 않음
iat: 토큰 발급 시간(issued at), 토큰 발급 이후의 경과 시간을 알 수 있음
jti: JWT 토큰 식별자(JWT ID), 중복 방지를 위해 사용하며, 일회용 토큰(Access Token) 등에 사용
사용자 정의 클레임으로 공개용 정보를 위해 사용된다. 충돌 방지를 위해 URL포멧을 이용한다.
사용자 정의 클레임으로 서버와 클라이언트 사이에 임의로 지정한 정보를 저장한다.
서명은 토큰을 인코딩하거나 유효성 검증을 할 때 사용하는 고유한 암호화 코드이다. 위에서 만든 헤더와 페이로드의 값을 각각 BASE64로 인코딩하고 이 값을 비밀 키를 이용해 헤더에서 정의한 알고리즘으로 해싱을 하고 다시 BASE64로 인코딩하여 생성한다.
JWT를 소개합니다.https://meetup.toast.com/posts/239
[JWT] JSON Web Token 소개 및 구조https://velopert.com/2389