불투명 토큰 vs JWT
불투명 토큰과 JWT의 차이점, 사용 사례, OIDC 기반 시스템에서 검증되는 방식 이해하기.
Logto에서는 OIDC 기반의 종합 CIAM 플랫폼으로서, 권한 부여 토큰이 사용자 상호작용을 보호하고 리소스 접근을 관리하는 데 중요한 역할을 합니다. 권한 부여에 사용되는 여러 유형의 토큰 중에서 불투명 토큰과 JWTs (JSON 웹 토큰)가 가장 중요합니다.
우리 커뮤니티에서 다음과 같은 질문을 받았습니다: 불투명 토큰과 JWT의 차이는 무엇인가요? 받는 액세스 토큰을 왜 디코딩할 수 없나요, 왜 토큰 길이가 짧아 보이나요? 이 블로그 포스트는 이러한 개념을 명확히 하고 불투명 토큰과 JWT의 구별점, 사용 사례, 그리고 활용 시 발생하는 다양한 행동을 이해하는 데 도움을 주고자 합니다.
불투명 토큰이란?
불투명 토큰은 액세스 토큰의 한 종류로, 이름 그대로 클라이언트나 외부 당사자에게 불투명하거나 비투명합니다. 즉, 토큰 자체는 사용자나 부여된 권한에 대한 읽을 수 있는 정보를 포함하지 않습니다.
불투명 토큰을 받았을 때, 그것은 종종 무작위 글자의 문자열처럼 보이고, 디코딩하려고 해도 의미있는 데이터를 얻게 되지 않습니다.
여기 불투명 토큰의 예시입니다:
토큰의 실제 내용은 발급한 권한 부여 서버만이 알고 있기 때문에 클라이언트는 토큰을 검증하려면 그것을 서버로 다시 보내서 서버가 진정성을 확인하고 관련 권한을 결정해야 합니다. 이 방식은 민감한 정보를 숨길 수 있어 추가적인 보안 층을 제공하지만, 토큰을 검증하기 위해 추가적인 서버 통신 이 필요합니다.
장점:
- 안전성: 불투명 토큰은 클라이언트에게 민감한 정보를 노출하지 않습니다. 토큰의 내용은 권한 부여 서버만이 알고 있습니다.
- 취소 가능성: 토큰은 서버에 저장되며, 권한 부여 서버의 인트로스펙션 엔드포인트를 통해서만 검증될 수 있기에, 서버는 필요시 토큰을 쉽게 취소하고 무단 접근을 방지할 수 있습니다.
- 작은 크기: 불투명 토큰은 일반적으로 JWT보다 짧아서 성능 및 저장 공간 측면에서 이점이 있을 수 있습니다.
단점:
- 상태 유지: 불투명 토큰은 토큰을 검증하기 위해 권한 부여 서버가 상태를 유지해야 하므로, 추가적인 복잡성과 부담을 초래할 수 있습니다.
- 성능: 토큰을 검증하기 위한 추가적인 서버 통신 필요는 특히 고트래픽 상황에서 성능에 영향을 미칠 수 있습니다.
JWT란?
불투명 토큰과는 대조적으로, JWT (JSON 웹 토큰)는 구조화되고 읽기 가능한 형식으로 정보를 지니는 독립적이고 무상태적인 토큰입니다.
JWT는 세 부분으로 구성됩니다: 헤더
, 페이로드
, 서명
각각 Base64URL로 인코딩됩니다.
여기 JWT의 예시입니다:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
헤더
는 토큰 타입과 서명에 사용된 알고리즘에 대한 정보를 포함합니다. 예:{"alg": "HS256", "typ": "JWT"}
.페이로드
섹션은 사용자 또는 권한 부여에 관한 정보 조각인 주장(claim)을 포함합니다. 사용자 ID, 만료 시간, 스코프처럼 이 데이터는 인코딩되어 있지만 암호화되어 있지 않기 때문에, 토큰을 가진 사람은 누구나 주장을 디코딩하여 볼 수 있지만, 서명을 무효화하지 않고 변경할 수는 없습니다. 명세 및 권한 부여 서버 설정에 따라 다양한 클레임이 페이로드에 포함될 수 있습니다. 이는 토큰이 자기 포함성을 갖도록 합니다. 예:{"sub": "1234567890", "name": "John Doe", "iat": 1516239022}
.서명
은 헤더, 페이로드, 특정 알고리즘을 사용한 비밀 키를 결합하여 생성됩니다. 이 서명은 토큰의 무결성을 검증하고 변조되지 않았음을 보장하는 데 사용됩니다.
JWT는 로컬에서 클라이언트 또는 서비스가 검증할 수 있기 때문에 독립적인 시스템에서 특히 효율적입니다. 이는 권한 부여 서버와 상호작용할 필요 없이 다수의 서비스가 독립적으로 토큰의 진정성을 검증할 수 있게 만들기 때문입니다.
하지만 이러한 편리함과 함께, 토큰의 주장(claim)이 지나치게 노출되지 않도록 보장해야 하는 책임도 따라옵니다. 토큰에 접근한 누구라도 그 정보를 볼 수 있기 때문입니다. 또한, JWT는 일반적으로 짧은 시간 동안만 유효하며, 토큰에 포함된 주장 속 만료 시간이 토큰의 무제한 유효성을 방지하기 위함입니다.
장점:
- 무상태: JWT는 자기 완결적이며 서버 측 상태를 필요로 하지 않습니다.
- 크로스 서비스 호환성: JWT는 다양한 서비스에서 쉽게 공유되고 검증될 수 있어 분산 시스템에 이상적입니다.
- 확장성: JWT의 페이로드는 사용자 정의 클레임을 포함할 수 있어 유연한 권한 부여와 정보 공유가 가능합니다.
- 표준: JWT 토큰은 잘 정의된 표준(RFC 7519)에 따라 만들어져, 널리 지원되고 상호 운용이 가능합니다.
단점:
- 노출: JWT의 주장(claim)은 토큰에 접근한 누구라도 볼 수 있어, 민감한 정보는 페이로드에 포함되어선 안 됩니다.
- 큰 크기: JWT는 담고 있는 추가 정보 때문에 불투명 토큰보다 클 수 있어 성능과 저장공간에 영향을 미칠 수 있습니다. JWT 토큰의 주장은 최소한으로 유지하여 토큰 크기를 줄여야 합니다.
- 취소의 복잡성: JWT는 무상태이기 때문에 일반적으로 짧은 시간 동안 유효하며, 만료 전에 토큰을 취소하는 내장 메커니즘이 없습니다. 즉, 손상된 토큰이 만료될 때까지 유효할 수 있습니다.
불투명 액세스 토큰 검증
불투명 액세스 토큰은 그것을 권한 부여 서버로 돌려보내 검증을 통해 인증됩니다. 권한 부여 서버는 발급된 토큰의 상태를 유지하며 내부 저장소를 기반으로 토큰의 유효성을 판단할 수 있습니다.
- 클라이언트가 권한 부여 서버에 액세스 토큰을 요청합니다.
- 권한 부여 서버는 불투명 토큰을 발급합니다.
- 클라이언트는 불투명 토큰을 함께 사용하여 리소스 접근 요청을 보냅니다.
- 리소스 공급자는 토큰 검증 요청을 권한 부여 서버에 전송합니다.
- 권한 부여 서버는 토큰 정보로 응답합니다.
JWT access token 검증 (오프라인)
JWT 액세스 토큰은 클라이언트 또는 토큰의 공개 키에 접근할 수 있는 모든 서비스에 의해 오프라인으로 검증될 수 있습니다.
- 리소스 공급자가 미리 권한 부여 서버의 공개 키를 OIDC 디스커버리 엔드포인트에서 가져옵니다. 이 공개 키는 토큰의 서명을 검증하고 그 무결성을 보장하는 데 사용됩니다.
- 클라이언트가 권한 부여 서버에 액세스 토큰을 요청합니다.
- 권한 부여 서버는 JWT 토큰을 발급합니다.
- 클라이언트는 JWT 토큰을 사용하여 리소스 접근 요청을 보냅니다.
- 리소스 공급자는 공개 키를 사용하여 JWT 토큰을 디코딩하고 검증합니다.
- 리소스 공급자는 토큰의 유효성에 따라 접근을 허가합니다.
OIDC에서의 사용 사례
OIDC (OpenID Connect) 컨텍스트에서 불투명 토큰과 JWT는 다른 목적으로 사용되며 각기 다른 시나리오에서 사용됩니다.
불투명 토큰
- 사용자 프로필 검색:
기본적으로 클라이언트가 리소스를 명시하지 않고 openid
범위를 포함하여 액세스 토큰을 요청했을 때, 권한 부여 서버는 불투명 액세스 토큰을 발급합니다. 이 토큰은 주로 OIDC /oidc/userinfo
엔드포인트에서 사용자 프로필 정보를 검색하는 데 사용됩니다. 불투명 액세스 토큰과 함께 요청을 받으면, 권한 부여 서버는 내부 저장소를 확인하여 관련 권한 정보를 검색하고 토큰의 유효성을 검증한 후 사용자 프로필 정보를 응답합니다.
- 갱신 토큰 교환:
갱신 토큰은 리소스 공급자와 공유할 필요 없이 클라이언트와 권한 부여 서버 간에만 교환되도록 설계되었습니다. 따라서 갱신 토큰 은 대개 불투명 토큰으로 발급됩니다. 현재 액세스 토큰이 만료되면, 클라이언트는 불투명 갱신 토큰을 사용하여 새로운 액세스 토큰을 받을 수 있으며, 사용자를 재인증하지 않고도 지속적인 접근을 보장합니다.
JWTs
- ID 토큰:
OIDC에서 ID 토큰은 사용자의 정보를 포함하는 JWT이며, 사용자 인증에 사용됩니다. 일반적으로 액세스 토큰과 함께 발급되어 클라이언트가 사용자의 신원을 검증할 수 있게 합니다. 예:
클라이언트는 ID 토큰을 검증하여 사용자의 신원을 확인하고 개인화 또는 권한 부여 목적으로 사용자 정보를 추출할 수 있습니다. ID 토큰은 일회용으로 사용해야 하며 API 리소스 인증에 사용하지 않아야 합니다.
- API 리소스 접근:
클라이언트가 특정 리소스 표시와 함께 액세스 토큰을 요청할 때, 권한 부여 서버는 해당 리소스에 액세스하기 위한 JWT 액세스 토큰을 발급합니다. JWT는 리소스 공급자가 클라이언트의 접근을 인증하는 데 사용할 수 있는 주장을 포함합니다. 예:
리소스 공급자는 다음을 확인하여 요청을 검증할 수 있습니다:
iss
: 토큰이 신뢰할 수 있는 권한 부여 서버에 의해 발급되었음을 확인합니다.sub
: 토큰과 관련된 사용자를 식별합니다.aud
: 토큰이 특정 리소스를 대상으로 하는지 확인합니다.scope
: 사용자에게 부여된 권한을 확인합니다.
결론
요약하면, 불투명 토큰과 JWT는 OIDC 기반 시스템에서 서로 다른 목적을 제공하며, 불투명 토큰은 안전하고 상태를 유지하는 방식으로 권한 부여를 지원하고, JWT는 자기 완결적이고 무상태적인 대안을 제공합니다. 이러한 토큰 유형 간 차이점과 그 사용 사례를 이해하는 것은 애플리케이션에서 안전하고 효율적인 인증 및 권한 부여 메커니즘을 설계하는 데 필수적입니다.
Logto에서 더 많은 액세스 토큰 기능을 알아보세요: