JWT란 JSON Web Token의 약자로 Json 포맷을 이용하여 두 당사자(발급자 및 대상) 간에 정보를 전송하는 Web Token입니다.
서버와 클라이언트 간 정보를 주고 받을 때 Http 리퀘스트 헤더에 JSON 토큰을 넣은 후 서버는 별도의 인증 과정없이 헤더에 포함되어 있는 JWT 정보를 통해 인증합니다.
JWT는 세 파트로 나누어지며, 각 파트는 점로 구분하여 xxxxx.yyyyy.zzzzz 이런식으로 표현됩니다. 순서대로 헤더(Header), 페이로드(Payload), 서명(Sinature)으로 구성합니다.
typ
, alg
두 가지의 정보를 지니고 있습니다.typ
: 토큰의 타입을 지정합니다. ex)JWTalg
: 해싱 알고리즘을 지정합니다.{ "alg": "HS256", "typ": JWT }
Payload
Payload 부분에는 토큰에 담을 클레임(claim) 정보가 들어있습니다. 여기에 담는 정보의 한 ‘조각’ 을 클레임(Claim) 이라고 부르고, 이는 Json(Key/Value) 형태의 한 쌍으로 이뤄져있습니다. 토큰에는 여러 개의 클레임들을 넣을 수 있습니다.
클레임의 정보는 등록된(registered) 클레임, 공개(public) 클레임, 비공개(private) 클레임으로 세 종류가 있습니다.
Signature
서명(Signature)은 위에서 만든 헤더(header)와 페이로드(Paylaod)의 값을 합친 문자열을 서명한 값이다. 서명은 헤더의 alg
에 정의된 알고리즘과 secret key
를 이용해 생성하고 Base64 URL-Safe
로 인코딩한다.
secret key를 포함해서 암호화가 되어있다.
Self-contained
토큰 자체에 정보를 담고 있으므로 양날의 검이 될 수 있습니다.
토큰 길이
토큰의 페이로드(Payload)에 3종류의 클레임을 저장하기 때문에, 정보가 많아질수록 토큰의 길이가 늘어나 네트워크에 부하를 줄 수 있습니다.
Payload 인코딩
페이로드(Payload) 자체는 암호화 된 것이 아니라, BASE64로 인코딩 된 것입니다. 중간에 Payload를 탈취하여 디코딩하면 데이터를 볼 수 있으므로, JWE로 암호화하거나 Payload에 중요 데이터를 넣지 않아야 합니다.
Stateless
JWT는 상태를 저장하지 않기 때문에 한번 만들어지면 제어가 불가능합니다. 즉, 토큰을 임의로 삭제하는 것이 불가능하므로 토큰 만료 시간을 꼭 넣어주어야 합니다.
Tore Token
토큰은 클라이언트 측에서 관리해야 하기 때문에, 토큰을 저장해야 합니다.
회원 인증
사용자가 로그인을 하면, 서버는 사용자의 정보를 기반으로한 토큰을 발급합니다.
그 후, 사용자가 서버에 요청을 할 때 마다 JWT를 포함하여 전달합니다. 서버는 해당 토큰이 유효하고 인증됐는지 검증을 하고, 사용자가 요청한 작업에 권한이 있는지 확인하여 작업을 처리합니다.
서버에서는 사용자에 대한 세션을 유지할 필요가 없습니다. 즉 사용자가 로그인되어 있는지 안되어 있는지 신경 쓸 필요가 없고, 사용자가 요청을 했을 때 토큰만 확인하면 되므로 세션 관리가 필요없어서 서버 자원과 비용을 절감할 수 있습니다.
정보 교류
JWT는 두 개체 사이에서 안정성있게 정보를 교환하기에 좋은 방법입니다. 그 이유는, 정보가 서명이 되어있기 때문에 정보를 보낸이가 바뀌진 않았는지, 또 정보가 도중에 조작되지는 않았는지 검증할 수 있습니다.