JWT는 JSON Web Token의 약자로 JSON 기반의 토큰이다. 디지털 서명 기반의 데이터 무결성을 보장한다.
인증 정보가 토큰에 담겨 있으므로, Stateless 서버에 적합하다.
HTTP Request Headers에 Authorization: Bearer ACCESS_TOKEN 형태로 포함시켜 사용한다.
JWT의 PAYLOAD는 BASE64 인코딩되어 있어 쉽게 디코딩하여 확인할 수 있다. 그렇기 때문에 PAYLOAD에 너무 많은 데이터를 담거나, 민감 정보를 담아서는 안된다
토큰의 탈취되어 사용되는 것을 막을 수는 없기 때문에 토큰의 유효기간을 짧게 설정하는 것이 좋다.
JWT는 HEADER, PAYLOAD, SIGNATURE의 3가지로 구성되어 있다.
HEADER는 해당 토큰이 JWT임을 알리고 해당 토큰을 서명하기 위해 어떤 알고리즘이 사용되었는지를 알려준다. 그리고 이 내용을 BASE64로 인코딩하여 JWT의 첫 번째 파트로 구성한다.
{
"alg": "HS256",
"typ": "JWT"
}
PAYLOAD는 JWT를 통해서 전달하고자 하는 실제 데이터가 담겨있는 곳이다.
일반적으로 전달하고자 하는 데이터와 해당 토큰의 발행 주체, 해당 토큰의 만료 시점의 부가 정보를 포함한다. 그리고 PAYLOAD에 담기는 각각의 정보들을 Claim이라고도 부른다.
JWT는 보통 사용자 인증에 주로 사용되고, PAYLOAD에 사용자 인증에 필요한 정보들을 Claim으로 작성한다.
PAYLOAD 또한 BASE64로 인코딩하고, JWT의 두 번째 파트로 구성하게 된다.
{
"sub": "1234567890",
"name": "kim",
"iat": 60000
}
SIGNATURE는 디지털 서명에 해당하는 부분이다. HEADER, PAYLOAD의 정보를 각각 BASE64로 인코딩한 다음, 이것을 다시 secret-key로 암호화하여 서명을 만든다.
이렇게 생성한 SIGNATURE를 JWT의 세 번째 파트로 구성한다.
SIGNATURE 값에는 HEADER, PAYLOAD의 정보가 각각 BASE64로 인코딩되어 있기 때문에 누군가가 이 토큰을 탈취해서 두 값을 수정하게 되면 기존 값과 값이 다르게 되어 검증에 실패하게 된다.
따라서 해당 토큰을 탈취 후 그대로 사용할 순 있겠지만 변조하는 것은 불가능에 가깝다.
HMACSHA256(
base64UrlEncoded(header) + "." +
base64UrlEncoded(payload),
<your-256-bit-secret-key>
)