JSON Web Tokens (JWT) are an open, industry standard [RFC 7519] method for representing claims securely between two parties. JWT는 웹표준(RFC 7519)으로서 두 개체 간에 JSON 객체를 사용하여 가볍고 자가수용적인 방식으로 정보를 안전하게 전달하는 방법입니다.
JWT는 마침표 .
을 구분자로 세 가지 문자열로 구성되어 있습니다.
예시: aaaa.bbbbb.ccccc
이 구조는 헤더(Header), 내용(Payload), 서명(Signature)으로 나뉩니다.
헤더는 typ
와 alg
두 가지 정보를 담고 있습니다.
typ
: 토큰의 타입을 지정합니다. JWT이기에 "JWT"
라는 값이 들어갑니다.alg
: 해싱 알고리즘을 지정합니다. 기본적으로 HMAC, SHA256, RSA 등이 사용되며, 토큰을 검증할 때 사용하는 서명 부분에서 이 알고리즘이 사용됩니다.{
"typ": "JWT",
"alg": "HS256"
}
Payload 부분에는 토큰에 담을 정보가 들어있습니다. 이 정보의 한 조각을 클레임(Claim)이라고 부르며, 이는 name/value의 한 쌍으로 이뤄져 있습니다. 여러 개의 클레임을 넣을 수 있지만, 너무 많아지면 토큰의 길이가 길어질 수 있습니다.
클레임의 종류는 크게 세 가지로 나눌 수 있습니다.
등록된 클레임들은 서비스에서 필요한 정보가 아닌, 토큰에 대한 정보들을 담기 위해 이름이 이미 정해진 클레임들입니다. 사용은 선택적(optional)이며, 포함된 클레임 이름들은 다음과 같습니다.
공개 클레임들은 충돌이 방지된(collision-resistant) 이름을 가지고 있어야 합니다. 이를 위해 클레임 이름을 URI 형식으로 짓습니다.
{
"https://example.com/jwt_claims/is_admin": true
}
등록된 클레임도 아니고, 공개된 클레임들도 아닌 클레임들로, 양 측간에(보통 클라이언트와 서버) 합의하에 사용되는 클레임 이름들입니다. 이름이 중복되어 충돌이 발생할 수 있으므로 주의해야 합니다.
서명은 헤더의 인코딩 값과 정보의 인코딩 값을 합친 후 주어진 비밀키로 해싱하여 생성합니다. 이렇게 만든 해쉬를 base64 형태로 나타냅니다.
JWT는 주로 로그인 인증에 사용되며, 유효기간이 짧은 토큰을 발급하게 되면 사용자가 자주 로그인을 해야 하기 때문에 번거롭습니다. 반대로, 유효기간이 긴 토큰을 발급하게 되면 제3자가 토큰을 탈취할 경우 보안에 취약해집니다.
이를 보완하기 위해 Refresh Token을 사용합니다. Refresh Token은 Access Token과 동일하게 JWT 형식을 취합니다. Access Token의 유효기간이 만료되었을 때, Refresh Token이 새로운 Access Token을 발급해주는 역할을 합니다.
예를 들어, Refresh Token의 유효기간이 1주, Access Token의 유효기간이 1시간이라고 가정할 때, 사용자는 Access Token으로 1시간 동안 API 요청을 할 수 있습니다. 만약 Access Token의 유효기간이 만료되면, Refresh Token을 이용해 새롭게 Access Token을 발급받습니다. 이렇게 하면 Access Token이 탈취당할 가능성이 적어지며, 탈취되어도 피해를 줄일 수 있습니다.
JWT는 웹 애플리케이션에서 인증 및 정보를 안전하게 전달하는 데 중요한 역할을 합니다. 그러나 보안 취약성을 최소화하기 위해서는 유효기간과 토큰 관리에 대한 신중한 설정이 필요합니다. 특히 Refresh Token을 사용하여 보안성을 높이고, 토큰 탈취로 인한 위험을 줄일 수 있습니다.