jwt 란?
여러가지 웹토큰의 형식 중 하나이며 가장 많이 쓰이는 json 형식의 토큰이다.
기존의 세션기반 인증은 서버가 파일이나 데이터베이스에 세션정보를 가지고 있어야 하고 이를 조회하는 과정이 필요하기 때문에 많은 오버헤드가 발생한다. jwt토큰은 서버가 인코딩한 정보를 클라이언트에게 던져주고 나면 이를 저장할 필요가 없다.
클라이언트는 요청할때마다 서버로부터 받은 토큰을 첨부해서 요청한다. 서버는 이 토큰이 자신이 만든 토큰인지 서명정보로 확인 검증한 후 정보를 제공한다.
jwt는 토큰자체에 데이터를 담을 수 있으며 구조는 아래와 같다.
구조
header.payload.signature
헤더.데이터.서명
header
[code]
{
“alg”: “HS256”,
“typ”: “JWT”
}
[/code]
alg: signature를 해싱하기 위한 알고리즘
– HS256(SHA256) or RSA
typ: 토큰의 타입
– 대부분 JWT
payload(데이터)
Claim이 담겨진 부분. Claim 이란 사용할 데이터의 조각을 말한다. 쉽게 말해 실제 사용할 정보.
json 형식으로 원하는 대로 넣을 수 있다.
payload 에는 Registered Claim 과 Public Cliam / Private Cliam 이 있다.
Registered Claim
이미 정해져 있는 데이터 형식으로서 사용여부는 선택이지만 웬만하면 사용할것을 권장하고 있다.
iss(issuer): 토큰 발급자
sub(subject): 토큰 제목. 일반적으로 이메일을 주로 쓴다.
aud(audience): 토큰 대상자
exp(expiration): 토큰 만료시간. unix time stamp 행식이다. ex) 1604534128
nbf(not before): 토큰이 유효하기 시작하는 시간. 이 날짜 이후부터 유효핟.
iat(issued at): 토큰이 발급된지 얼마나 됐는지 경과 시간
jti(JWT ID): 중복을 방지하기 위해서 사용되고 일회성 토큰(Access Token)등에 사용된다.
Public Cliam
사용자 정의 데이터이며 공개용 데이터를 위해 사용된다. 이미 정해져 있는 데이터(Registered Claim) 의 변수와 중복되지 않게 보통 URI 형식으로 사용한다.
형식: { URI/변수: 값 }
ex)
{ “http://hacktam.kr/is_member”: true }
Private Cliam
사용자 정의 데이터이며 서버와 클라이언트끼리만 사용하는 비공개 데이터를 위해 사용된다. 특정한 형식이 따로 없으므로 Registered Claim 과 중복되지 않도록 주의한다.
[code]
{
“foo”: “ABC”,
“bar”: “false”
}
[/code]
claim 예)
[code]
{
“iss”: “http://example.org”,
“aud”: “https://exmple.com”,
“exp”: “1604534128”,
“http://hacktam.kr/claims/is_member” : “true”,
“user_id”: “admin”
}
[/code]
Signature(서명)
클라이언트에게 넘겨줄 토큰을 인코딩하거나 클라이언트로부터 받은 토큰이 유효한지 검증할때 사용되는 코드이다.
생성과정
1. header 에서 정의한 알고리즘(alg) 을 추출한다.
2. header 와 payload 를 base64로 인코딩한다.
3. 2에서 인코딩한 결과를 1의 알고리즘으로 해싱한다.
4. 3의 결과를 base64로 인코딩하여 최종 Signature 를 생성한다.