1. JSON 웹 토큰이란?
당사자 간에 정보를 JSON 개체로 안전하게 전송하기 위한 방법을 정의하는 개방형 표준(RFC7519)입니다.
전송하는 정보는 디지털 서명이 되어 있어(발신자 확인 및 정보 위변조 방지) 신뢰할 수 있습니다.
HMAC 알고리즘 또는 RSA 및 ECDSA 를 사용하는 비대칭 암호화 방식(공개/개인 키 쌍)을 사용하여 서명할 수 있습니다.
서명된 토큰을 사용하여 전송하는 정보를 숨기고,
비대칭 키를 통해 개인 키를 가지고 있는 사람만 인증합니다.
정보 전송을 위한 방법 중 하나로, 암호화를 통해 서명하여 신뢰도가 높습니다.
인증을 통해 토큰을 발급하고, 토큰에 권한을 부여하여 사용할 수 있습니다.
2. 사용 예시
액세스 승인과 정보 교환에 사용할 수 있습니다.
1. 액세스 승인
사용자 인증
후속 요청마다 인가된 토큰을 함께 보냄
해당 토큰의 권한에 따라 경로, 서비스, 및 리소스에 액세스
OAuth 2.0 및 SSO에서 JWT방식을 사용합니다 (Single Sign On - 1회 인증으로 다수의 요청을 허용)
2. 정보 교환
당사자 간의 정보를 안전하게 전송할 수 있습니다.
비대칭 키 암호화를 사용하여 정보를 보낸 사람이 누구인지 확인할 수 있으며,
헤더와 페이로드를 사용하여 서명을 작성하므로 콘텐츠 변조를 확인할 수 있습니다.
3. 구조
3가지로 구성되어있으며, 점( . )으로 구분합니다.
xxx.yyyyyyy.zzz
헤더.페이로드.서명
헤더
헤더는 일반적으로 토큰 유형과 서명 알고리즘(어떤 암호화 유형을 사용할지)을 기재합니다.
{
"alg" : "HS256"
"typ" : "JWT"
}
그 다름 이 JSON은 Base64Url 로 인코딩되어 JWT의 첫 부분을 구성합니다
페이로드
페이로드는 토큰의 두 번째 부분이며 클레임(claim)을 포함합니다.
claim 클레임
클레임은 엔터티 및 추가 데이터에 대한 설명입니다
일반적으로 사용자에 대한 정보를 담습니다
클레임에는 등록된 클레임, 공개 클레임, 비공개 클레임 세 가지 유형이 있습니다.
등록된 클레임
미리 정의된 클레임 집합으로 사용을 권장합니다.
iss(발행자), exp(만료 시간), sub(주제), aud(수신자), iat(발행 시간) 등이 있습니다.
{
"iss": "발행자",
"exp": 만료 시간,
"iat": 발행 시간,
"sub": "주제",
"aud": "수신자",
}
(참조: https://tools.ietf.org/html/rfc7519#section-4.1)
공개 클레임
원하는 대로 정의할 수 있습니다.
기존에 정의된 내용과 충돌할 수 있으니,
충돌을 방지하려면
충돌 방지 네임스페이스를 포함하는 URI로 정의하거나
IANA JSON 웹 토큰 레지스트리를 참조하여 정의합니다
(참조: https://www.iana.org/assignments/jwt/jwt.xhtml)
비공개 클레임
사용에 동의한 당사자 간 정보를 공유하기 위해 정의한 맞춤형 클레임 입니다.
(등록 및 공개 클레임이 아닌 클레임이며, 당사자와 합의하여 정의합니다)
{
"sub": "1234567890", // 등록된 클레임
"name": "John Doe", // 공개 클레임(IANA JSON 웹 토큰 레지스트리에 정의된 것)
"<http://example.com/is_root>":true, -> 공개 클레임(URI로 정의한 것)
"admin": true // 비공개 클레임(직접 정의한 것)
}
그 다음, 페이로드는 Base64Url로 인코딩되어 JWT의 두 번째 부분을 구성합니다.
서명된 토큰의 경우 이 정보는 변조로 부터 보호할 수 있지만, 누구나 읽을 수 있습니다.
따라서 비밀 정보(암호화 되지 않은 비밀번호)를 페이로드에 넣지 않아야 합니다.
{
...
"pw": "userPassword123!" // 이 비밀번호는 누구나 열람할 수 있습니다.
...
}
서명
서명 부분은, 인코딩된 헤더와 인코딩된 페이로드, 비밀번호(따로 정의해야 합니다), 헤더 알고리즘을 통해 생성됩니다.
HMAC SHA256 알고리즘을 사용하는 예시
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
서명을 통해 메시지의 위변조를 확인하며, 개인 키로 서명된 토큰의 경우 발신자를 확인할 수 있습니다.
출력은 HTML 및 HTTP 환경에서 쉽게 전달할 수 있으며,
점으로 구분된 3개의 Base64-URL 문자열입니다.
SAML과 같은 XML 기반 표준과 비교할 때 더 간결합니다.
JWT 예시
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
(jwt.io 디버거를 사용하여 JWT를 디코딩, 확인 및 생성할 수 있습니다)
4. 작동
인증 시 사용자가 자격 증명을 사용하여 성공적으로 로그인하면 JWT가 반환됩니다.
토큰은 자격 증명이므로 보안 문제를 방지하기 위해 세심하게 관리할 필요가 있습니다.
만료기간을 길게 설정하지 말기
(토큰의 만료 시점을 변경할 수 없기에 신중할 필요가 있습니다)
(토큰사용 중, 액세스 토큰의 기간이 만료되면 리프레시 토큰을 통해 재발급합니다)
브라우저 저장소에 저장하지 말기
(토큰이 탈취될 수 있습니다)
일반적으로 Bearer 스키마를 사용하여 Authorization 헤더에 JWT를 보내야 합니다.
Authorization : Bearer <token>
- 애플리케이션이나 클라이언트가 인증 서버에 인증을 요청합니다. 이는 다양한 인증 흐름 중 하나를 통해 수행됩니다. 예를 들어 일반적인 OpenID Connect 호환 웹 애플리케이션은 인증 코드 흐름에서 /oauth/authorize 형식을 사용하여 엔드포인트를 통과합니다 .
- 권한이 부여되면 권한 서버는 애플리케이션에 액세스 토큰을 반환합니다.
- 애플리케이션은 액세스 토큰을 사용하여 보호된 리소스(예: API)에 액세스합니다.
- 사용자가 브라우저에서 로그인
- 서버에서 인증 후 JWT 생성
- 서버에서 사용자에게 JWT 반환
- 이후 사용자는 요청을 할 때마다 헤더의 Authorization 에 토큰을 담아서 요청
- 서버에서 토큰에 있는 권한만 확인
- 서버에서 요청을 처리한 결과를 사용자에게 전달
5. 장단점
장점
1. JWT는 인가(Authorization)를 포함하기 때문에 사용자의 인가 여부를 확인하기 위해 추가적으로 DB를 조회하지 않아도 됩니다.
2. JSON 형태의 포맷으로, 간결하며 가벼우며 다루기 쉽습니다.
3. (페이로드에 담는 클레임을 통해)사용자의 정보를 유연하게 저장하여 사용할 수 있습니다.
단점
1. 토큰의 유효기간을 변경할 수 없기에, 따로 설정을 하지 않으면 탈취 시 대처할 수 없습니다.
2. 따로 설정을 하지 않으면, 페이로드가 담고 있는 정보의 양에 따라 토큰의 크기가 방대해집니다.
3. 보안을 위한 관리가 복잡해질 수 있습니다. 토큰 서명에 필요한 비밀번호가 노출되지 않도록 해야하며, 리프레시 토큰을 통해 관리할 수도 있습니다.
6. 결론
JWT는 인증 및 인가를 위해 사용하는 표준화된 방법이며 SSO, OAuth 등 널리 사용되고 있습니다.
토큰 유형과 암호화 알고리즘을 설정하는 헤더,
사용자 정보와 토큰에 대한 각종 설정을 하는 페이로드,
헤더와 페이로드를 통해 생성하고 발신자 및 토큰 위조를 확인하는 서명 이렇게 3가지로 구성되어 있으며
헤더, 페이로드, 서명을 점으로 구분합니다.
작동방식은 다음과 같습니다.
서버에서 사용자가 인증(authentication)되면 인가(authorization)된 토큰을 발급하여 사용자에게 제공합니다.
이후 사용자가 서버에 권한이 필요한 요청할 때마다 토큰의 인가(authorization)정보를 확인하여 응답합니다.
JWT은 사용자의 정보를 유연하게 다룰 수 있으며, 사용자의 요청마다 DB를 추가적으로 조회하지 않아도 되기 때문에 서버의 부하를 줄여주는 장점이 있으나,
서명된 토큰은 변경하기 힘들고 탈취 시 악용될 수 있기 때문에 각별한 관리가 필요하며,
관리 과정에 따라 시스템이 복잡해질 수 있습니다.
관리 과정에서 리프레시 토큰(RT, Refresh Token) - 액세스 토큰(AT, Access Token)방식을 사용할 수 있으며,
액세스 토큰의 기한을 짧게 설정하여 리프레시 토큰으로 재발급하는 방식입니다.
어떻게 설정하는가에 따라 세부적인 사항이 달라질 수 있으며 개인정보에 관한 것이기 때문에 고심할 필요가 있습니다.
7. 참조
https://datatracker.ietf.org/doc/html/rfc6749
'Dictionary' 카테고리의 다른 글
[Dictionary] Bootstrap (1) | 2023.12.29 |
---|---|
OAuth 2.0 개요 (1) | 2023.10.15 |
클라우드의 서비스 제공 형태 XaaS, SaaS, PaaS, IaaS (0) | 2023.09.26 |
CI/CD 란? (0) | 2023.09.23 |
프록시(Proxy)란? (0) | 2023.09.20 |