JSON 웹 토큰(JWT)은 온라인 네트워크에서 정보를 안전하게 통신할 때 사용하는 인터넷 표준 토큰입니다. JWT는 간결하고 URL에 안전하게 사용할 수 있다는 장점이 있습니다. 프로토콜의 자세한 내용이 궁금하다면 RFC 7519를 참고해주세요.
JWT는 인증, 정보 교환 등 다양한 용도에 사용됩니다. 이때 주고받는 정보를 클레임(Claim)이라고 하고, 클레임의 집합은 JSON 객체로 표현해요.
JWT에는 두 가지 유형이 있어요. 더 널리 사용되는 첫 번째 방식은 JWS(JSON Web Signature)입니다. JWS 방식을 사용하면 클레임의 내용은 누구나 읽을 수 있지만 서명이 있기 때문에 데이터의 무결성이 보장돼요. 두 번째 방식은 JWE(JSON Web Encryption)입니다. JWE에서는 클레임 자체를 암호화합니다. 그래서 복호화 방법을 알고 있는 사용자만 페이로드를 읽을 수 있어요.
보안 측면에서는 JWE가 더 안전합니다. 그렇기 때문에 토스페이먼츠도 지급대행과 같은 서비스에 JWE를 사용하고 있어요. 하지만 페이로드의 데이터를 클라이언트가 바로 사용해야 된다면 JWS가 더 편리하고 데이터의 무결성을 보장할 수 있어요. 용도의 보안, 사용성을 고려해서 JWT 방식을 선택해주세요.
JWS, JWE 둘 다 구성은 같습니다. 헤더, 페이로드, 서명 세 가지 주요 요소로 구성되고 각 구성은 .
마침표를 구분자로 사용해요. 아래는 JWS의 예시입니다. 편의를 위해 여러 줄에 나누었지만, 실제 JWS는 줄바꿈이 없는 문자열입니다.
- 헤더(Header): 일반적으로 헤더에는 토큰의 유형(JWS, JWE)과 서명 알고리즘을 명시해요. JSON으로 표현된 헤더를 Base64로 인코딩한 것이 JWT 헤더입니다.
- 페이로드(Payload): 보통 JSON 형식으로 표현된 사용자의 정보나 클레임이 키-값(key-value)로 포함된 부분입니다. RFC 7519에 정의된
iss
(issuer),exp
(expiration time),sub
(subject),aud
(audience) 등 키를 사용할 수 있지만, 필요에 따라 새로운 클레임을 추가할 수도 있어요. JWS 방식에서는 페이로드도 Base64로 인코딩합니다. 누구나 디코딩할 수 있기 때문에 JWS 페이로드에는 민감한 정보를 넣으면 안 돼요. JWE 방식에서는 페이로드를 안전한 알고리즘과 비밀 키로 암호화하기 때문에 민감한 정보를 포함할 수 있어요. - 서명(Signature): 헤더와 페이로드를 결합한 후 지정된 알고리즘과 비밀 키 또는 공개 키로 서명한 값입니다. 이 서명은 JWT의 무결성을 보장하며, 데이터가 변경되지 않았음을 확인할 수 있습니다. 서명을 아래와 같은 형태입니다. 인코딩한 헤더, 페이로드를 헤더에 정의한 알고리즘에 의해
secret
(키)으로 암호화합니다. 서명은 키로만 복호화할 수 있기 때문에 토큰의 전송자와 내용의 무결성을 보장합니다.
JWT에는 어떤 장점과 특징이 있을까요?
먼저 JWT는 독립적(Stateless)입니다. 필요한 정보를 모두 자체적으로 들고 있어서 서버 측에서 세션을 저장할 필요가 없어요. 이런 특징 덕분에 JWT를 이용하면 서버 부하를 줄일 수 있고 확장성을 확보할 수 있어요.
다음으로 JWT를 사용하면 무결성이 보장됩니다. JWS는 서명을 통해 토큰이 변조되지 않았음을 확인할 수 있어요. JWE는 페이로드를 암호화하기 때문에 데이터의 기밀성까지 보장할 수 있고요.
마지막으로 JWT는 간결하고, URL에서 안전하게 사용할 수 있습니다. 모바일 기기 및 웹 애플리케이션에서 클라이언트가 편리하게 파싱하고 이용할 수 있어요. 아래 그림은 JWT 와 SAML 인코딩을 비교하고 있어요.
이미지 출처: JWT.io