-
Notifications
You must be signed in to change notification settings - Fork 1
JWT란?!
JSON Web Token은 웹표준으로 두 개체에서 JSON 객체를 사용하여 가볍고 자가 수용적인(self-contained) 방식으로 정보를 안정성 있게 전달해준다.
JWT 는 필요한 모든 정보를 자체적으로 지니고 있습니다.
JWT 시스템에서 발급된 토근은, 토큰에 대한 기본 정보, 전달 할 정보 ( 로그인 시스템에서는 유저 정보) 그리고 토큰이 검증되었다는 것을 증명해주는 signature를 포함하고 있다.
- 토큰의 기본 정보
- 전달 할 정보
- 토큰의 서명
JWT 는 자가 수용적이므로, 두 개체 사이에서 손쉽게 전달 될 수 있다. 웹 서버의 경우 HTTP의 헤더에 넣어서 전달 할 수도 있고, URL의 파라미터로 전달 할 수도 있다.
다음과 같은 상황에서 JWT가 유용하게 사용 될 수 있다.
- 회원 인증
- 정보 교류
JWT를 사용하여 가장 흔한 시나리오이다.
유저가 로그인을 하면, 서버는 유저의 정보에 기반한 토큰을 발급하여 유저에게 전달해준다. 그 후, 유저가 서버에 요청을 할 때 마다 JWT 토큰을 포함하여 전달한다.
서버가 클라이언트에게서 요청을 받을때 마다, 해당 토큰이 유효하고 인증됐는지 검증을 하고, 유저가 요청한 작업에 권한이 있는지 확인하여 작업을 처리한다.
서버측에서는 유저의 세션을 유지 할 필요가 없다. 즉 유저가 로그인 되어 있는지 안 되어 있는지 신경 쓸 필요가 없고, 유저가 요청을 했을때 토큰만 확인하면 되니, 세션 관리가 필요 없어서 서버 자원을 많이 아낄 수 있다.
JWT는 두 개체 사이에서 안정성있게 정보를 교환하기에 좋은 방법이다. 그 이유는, 정보가 sign이 되어있기 때문에 정보를 보낸이가 바뀌진 않았는지, 또 정보가 도중에 조작되지 않았는지 검증할 수 있다.
JWT는 .
을 기준으로 3가지의 문자열로 되어있다. 구조는 다음과 같이 이루어져있다.
JWT 토큰을 만들때는 JWT를 담당하는 라이브러리가 자동으로 인코딩 및 해싱 작업을 해준다.
Header 는 두 가지의 정보를 지니고 있다.
-
typ : 토큰의 타입을 지정한다. JWT 이다.
-
alg : 해싱 알고리즘을 지정한다. 해싱 알고리즘은 보통 HMAC SHA256 혹은 RSA가 사용되며, 이 알고리즘은 토큰을 검증 할 때 사용되는 signature 부분에서 사용된다.
{ "typ" : "JWT" "alg" : "HS256" //해싱 알고리즘으로 HMAC SHA256을 사용한다. }
참고로 JSON 형태의 객체가 base64로 인코딩 되는 과정에서 공백 / 엔터들이 사라진다. 따라서 다음과 같은 문자열을 인코딩 하게 된다.
{"alg":"HS256","typ":"JWT"}
Payload 부분에는 토큰에 담을 정보가 들어있다. 여기에 담는 정보의 한 조각
을 클레임(Claim) 이라고 부르고, 이는 name / value 의 한 쌍으로 이루어져있다. 토큰에는 여러개의 클레임 들을 넣을 수 있다. 클레임의 종류는 다음과 같이 크게 세 분류로 나위어져 있다.
- 등록된(Registered) 클레임,
- 공개(Public) 클레임,
- 비공개(Private) 클레임
등록된 클레임들은 서비스에서 필요한 정보들이 아닌, 토큰에 대한 정보를 담기 위하여 이름이 이미 정해진 클레임 들이다. 등록된 클레임의 사용은 모두 선택적 (Optional) 이며, 이에 포함된 클레임 이름들은 다음과 같다.
- iss : 토큰 발급자
- sub : 토큰 제목
- aud : 토큰 대상자
- exp : 토큰의 만료시각, 시간은 항상 NumericDate 형식으로 되어 있어야 하며 언제나 현재 시간보다 이후로 설정되어 있어야 한다.
- nbf : Not Before를 의미하며, 토큰의 활성 날짜와 비슷한 개념이다. 여기에도 NumericDate형식으로 되어야 하며 이 날짜가 지나기 전까지는 토큰이 처리되지 않는다.
- iat : 토큰이 발급된 시간, 이값을 사용하여 토큰의 age 를 판단 할 수 있다.
- jti : JWT의 고유 식별자로, 주로 중복적인 처리를 방지하기 위하여 사용된다. 일회용 토큰에 사용하면 유용하다.
공개 클레임들은 충돌이 방지된 (Collision-resistant) 이름을 가지고 있어야 된다. 충돌을 방지하기 위해서는 클레임 이름을 URI 형식으로 짓는다.
{
"https:www.naver.com/alswns" : true
}
등록된 클레임도 아니고, 공개된 클레임도 아니다. 양 측간에 (보통 클라이언트 와 서버) 합의하에 사용되는 클레임 이름들이다. 공개 클레임과는 달리 임름이 중복되어 충돌이 될 수 있으니 사용할때에 유의해야 된다.
{
"username" : "alswns"
}
{
"iss" : "alswns.com",
"exp" : "1485270000000",
"https://naver.com/alswns" : true,
"userId" : "1128373727102",
"username" : "alswns"
};
JSON Web Token 의 마지막 부분은 바로 서명(signature) 이다.
이 서명은 헤더의 인코딩값과 정보의 인코딩값을 합친 후 주어진 비밀키로 해쉬를 하여 생성한다.
헤더 + 정보 + 비밀키 → 해쉬 → 서명
해싱은 같은 인풋에 대해서 항상 같은 아웃풋이 나와야 된다.
따라서 헤더, 정보에서 임의의 변조가 일어났으면 변조된 값을 해싱하면 서명이 나오지 않아서 변조됨을 알 수 있다.
HS256 알고리즘이라고 하였는데 여기서 HS256은 HMAC SHA256의 합친말이다.
HMAC는 해싱기법을 이용해서 메시지의 위변조가 있었는지 체크하는 기법이다.
앞의 헤더, 페이로드 부분을 다시 해싱하였을 때 뒤에 서명이 나오는지 확인하는 방법이다.
해싱을 할 때 헤더 + 페이로드 + secret key 이렇게 세 개의 부분을 합쳐서 해싱을 하게 된다.