JSON Web Token
의 약어를 말한다. JSON 포맷을 이용하여 사용자에 대한 속성을 저장하는 Claim 기반의 Web Token이다. JWT는 토큰 자체를 정보로 사용하는 Self-Contained 방식으로 정보를 안전하게 전달한다. 주로 회원 인증이나 정보 전달에 사용된다.
유저가 로그인에 성공한 후에는 access token이라고 하는 암호화된 유저 정보를 첨부해서 request를 보내게 된다. 그러면 서버에서는 access token을 복호화 해서 해당 유저 정보를 얻게 된다.
access token
을 생성하는 방법은 여러가지가 있는데, 그 중 가장 널리 사용되는 기술중 하가 바로 JWT(JSON Web Tokens)이다.✔️ JWT는 헤더, 내용, 서명 세 가지 구조로 이루어져 있다.
토큰의 헤더는 typ과 alg 두 가지 정보로 구성된다. typ는 토큰 유형을 나타내며, alg는 사용중인 서명 알고리즘을 나타낸다. 이후 Base64Url로 인코딩되어 JWT의 header 부분을 형성하게 된다.
{
"alg": "HS256",
"typ": "JWT"
}
토큰의 페이로드에는 토큰에서 사용할 정보의 조각들인 클레임(Claim)이 담겨 있다. 클레임은 총 3가지 (registered claims, public claims, private claims) 로 나누어지며, Json(Key/Value) 형태로 다수의 정보를 넣을 수 있다.
– 유용하고 상호 운용 가능한 클레임을 제공하기 위해 필수는 아니지만 권장되는 미리 정의된 클레임 집합이다. 그중 일부는 iss (issuer), exp (expiration), sub (subject), aud (audience) 등이 있다.
– 공개 클레임들은 충돌이 방지된 (collision-resistant) 이름을 가지고 있어야 한다. 충돌을 방지하기 위해서는, 클레임 이름을 URI 형식으로 짓는다.
– 등록된 클레임도아니고, 공개된 클레임들도 아니다. 클라이언트-서버 협의하에 사용되는 클레임 이름들이다. 공개 클레임과는 달리 이름이 중복되어 충돌이 될 수 있으니 사용할 때 유의해야 한다.
{
"sub": "12345",
"name": "Gil Dong",
"admin": true
}
서명(Signature)은 토큰을 인코딩하거나 유효성 검증을 할 때 사용하는 고유한 암호화 코드이다. 서명(Signature)은 위에서 만든 헤더 (Header)와 페이로드 (Payload)의 값을 각각 BASE64로 인코딩하고, 인코딩한 값을 비밀 키를 이용해 헤더 (Header)에서 정의한 알고리즘으로 해싱을 하고, 이 값을 다시 BASE64로 인코딩하여 생성한다. 즉 서명 부분을 만들기 위해서는 인코딩된 헤더, 인코딩된 페이로드, secret, 헤더에 지정된 알고리즘을 가져와 야합니다.
✔️ JSON 방식의 단점 또한 분명하게 존재한다.
토큰이 만료되면 사용자는 다시 인증해야 하는 번거로움이 생길 수 있다.
토큰은 브라우저에서 삭제 되더라도 만료될 때까지 유효하므로 실질적인 로그 아웃이 불가능하다. 따라서 토큰 만료 시간을 꼭 넣어주어야 한다.
Self-contained, 즉 토큰 자체에 정보를 담고 있으므로 이것 자체로 양날의 검이 될 수 있다.
토큰의 내용 (Payload)에 3종류의 클레임을 저장하기 때문에, 정보가 많아질수록 토큰의 길이가 늘어나 네트워크에 부하를 줄 수 있다.
내용 (Payload) 자체는 암호화 된 것이 아니라, BASE64로 인코딩 된 것이다. 중간에 Payload를 탈취하여 디코딩하면 데이터를 볼 수 있으므로, JWE로 암호화하거나 Payload에 중요 데이터를 넣지 않아야 한다.
참고 자료
http://yoonbumtae.com/?p=3535
https://mangkyu.tistory.com/56
https://velog.io/@geunwoobaek/JWT%EB%9E%80