한국어
  • OAuth
  • client
  • public
  • confidential
  • PKCE

공개 및 비공개 클라이언트의 차이점은 무엇인가요?

이 문서에서는 OAuth에서 공개 클라이언트와 비공개 클라이언트의 차이를 Logto 애플리케이션을 예로 들어 설명합니다.

Darcy Ye
Darcy Ye
Developer

Logto를 사용하여 애플리케이션을 생성할 때, 단일 페이지 애플리케이션(SPA), 네이티브 앱, 그리고 전통적인 웹 애플리케이션과 같은 여러 애플리케이션 유형을 선택할 수 있다는 것을 알 수 있습니다. 직관적으로 이름에서 알 수 있듯이 네이티브 앱은 휴대전화와 같은 기기에서 흔히 볼 수 있는 운영 체제에서 실행됩니다. 그러나 SPA와 전통적인 웹 애플리케이션은 정확히 무엇일까요? 이 다양한 유형의 앱을 구분해야 하는 이유는 무엇일까요? 이 글을 통해 이러한 질문에 대한 답을 알아보겠습니다.

시작하기 전에 몇 가지 개념에 대한 간단한 소개를 제공할 필요가 있습니다.

OAuth란 무엇인가요?

OAuth는 접근 위임을 위한 공개 표준으로, 일반적으로 인터넷 사용자가 비밀번호를 제공하지 않고 다른 웹사이트의 정보에 접근할 수 있도록 웹사이트나 애플리케이션에 권한을 부여하는 방법으로 사용됩니다.

최근 10년간 점차 표준 권한 부여 프로세스로 자리 잡았으며 Google, Meta, Microsoft 등 대부분의 회사에서 널리 수용되었습니다. 현재 사용중인 버전은 OAuth 2.0입니다.

OAuth의 맥락에서, 우리가 이전에 언급한 애플리케이션은 클라이언트로 통칭됩니다. 이들은 자원 소유자(일반적으로 최종 사용자)의 승인을 얻은 경우, 보호된 자원에 대한 요청을 할 수 있습니다.

공개 클라이언트와 비공개 클라이언트

OAuth는 클라이언트 자격 증명을 유지하는 능력에 따라 두 가지 클라이언트 유형을 정의합니다.

비공개 클라이언트

자격 증명을 유지할 수 있는 클라이언트(예: 클라이언트 자격 증명에 대한 접근이 제한된 보안 서버에 구현된 클라이언트) 또는 다른 방법을 통해 안전한 클라이언트 인증이 가능한 클라이언트입니다.

공개 클라이언트

자격 증명을 유지할 수 없는 클라이언트(예: 네이티브 앱이나 웹 기반 앱 등 자원 소유자의 기기에서 실행되는 클라이언트)로, 다른 어떤 방법으로도 클라이언트로서 안전하게 인증할 수 없습니다.

SPA, 네이티브 애플리케이션 및 전통적인 웹 애플리케이션

위에서 언급한 배경 지식을 바탕으로, Logto의 맥락에서 SPA, 네이티브 앱 및 전통적인 웹 앱이 의미하는 바와 이를 공개 클라이언트나 비공개 클라이언트로 간주해야 하는지를 살펴보겠습니다.

SPA

SPA의 클라이언트 측 코드는 웹 서버에서 다운로드되며, 자원 소유자의 기기에서 사용자 에이전트(예: 웹 브라우저)에서 실행됩니다. 프로토콜 데이터와 자격 증명은 자원 소유자에게 쉽게 접근 가능(또는 일반적으로 보임)합니다.

네이티브 앱

네이티브 앱은 자원 소유자의 기기에 설치되고 실행됩니다. 프로토콜 데이터와 자격 증명은 자원 소유자에게 접근 가능합니다. 일반적으로 애플리케이션 내에 포함된 모든 클라이언트 인증 자격 증명은 추출될 수 있다고 가정합니다.

전통적인 웹 앱

전통적인 웹 앱은 웹 서버에서 실행되는 클라이언트입니다. 자원 소유자는 그들의 기기에서 사용자 에이전트에 표시되는 HTML 사용자 인터페이스를 통해 클라이언트에 접근합니다. 클라이언트 자격 증명과 클라이언트에게 발급된 모든 액세스 토큰은 웹 서버에 저장되며 자원 소유자에게 노출되거나 접근할 수 없습니다.

따라서 SPA와 네이티브 앱은 공개 클라이언트이고, 전통적인 웹 앱은 비공개 클라이언트라는 것을 명확히 알 수 있습니다.

Logto에서 SPA나 네이티브 앱을 생성할 때 앱 비밀이 없고, 전통적인 웹 앱에는 앱 ID와 앱 비밀이 모두 있는 것을 알 수 있습니다. 이는 공개 클라이언트의 비밀이 안전하게 보장될 수 없기 때문입니다.

OAuth 권한 부여 흐름에서 클라이언트는 어떻게 작동하나요?

OAuth 애플리케이션을 개발할 때 첫 번째 단계는 OAuth 서비스 제공자에게 클라이언트를 등록하는 것입니다. 클라이언트 등록은 애플리케이션 이름과 리다이렉트 URI와 같은 애플리케이션의 세부 정보를 제공하는 것으로 이루어집니다. 그런 다음, OAuth 서비스 제공자는 클라이언트 ID와 클라이언트 비밀을 생성합니다. 이는 애플리케이션의 자격 증명으로 간주됩니다.

클라이언트 ID는 공개 정보로 간주되며 OAuth 프로세스 동안 사용자와 공유됩니다. 일반적으로 권한 부여 URL에 포함되어 최종 사용자에게 표시됩니다.

반면 클라이언트 비밀은 애플리케이션의 비밀번호 역할을 하며 비공개로 유지되어야 합니다. 이는 OAuth 프로세스에서 권한 부여 코드를 교환(권한 부여 코드 흐름을 가정할 때)하여 액세스 토큰을 획득하는 데 사용됩니다. 클라이언트 비밀의 존재는 등록된 애플리케이션만이 액세스 토큰 교환을 완료할 수 있도록 보장합니다.

코드 교환을 위한 증명 키(PKCE) 소개

앞서 언급한 바와 같이, 공개 클라이언트의 클라이언트 비밀은 안전하게 보장될 수 없으며, 공격자는 클라이언트 자격 증명을 얻어 클라이언트를 가장하여 보호된 자원에 접근할 수 있습니다. 이는 어떤 상황에서도 용납될 수 없습니다.

PKCE(Proof Key for Code Exchange)는 각 권한 부여 흐름의 시작 시 임시로 코드 검증자를 생성하고 이를 로컬에 저장하고 해시하여 권한 부여 서버로 코드 챌린지를 보냄으로써 이 문제를 해결합니다. 코드 검증자는 액세스 토큰을 교환할 때 다시 권한 부여 서버로 보내집니다. 권한 부여 서버는 코드 검증자와 코드 챌린지를 확인하여 공개 클라이언트가 가장되지 않았는지 확인합니다.

PKCE의 코드 검증자는 실제로 동적인 클라이언트 비밀 역할을 합니다. 해시 알고리즘의 비가역성에 의해 그 보안이 보장됩니다.

요약

이 글에서는 OAuth에서 비공개 클라이언트와 공개 클라이언트의 개념에 대해 논의했습니다. 비공개 클라이언트는 비밀을 유지하고 민감한 정보를 안전하게 저장할 수 있는 능력을 가진 반면, 공개 클라이언트는 이러한 능력이 부족하다는 것을 배웠습니다. Logto의 제품 실습의 맥락에서 전통적인 웹 앱, SPA 및 네이티브 앱을 비롯한 두 유형의 클라이언트 예제를 살펴보았습니다.

또한, OAuth에서 클라이언트 등록 프로세스와 클라이언트 ID 및 클라이언트 비밀의 역할에 대해 논의했습니다.

게다가, 공개 클라이언트는 클라이언트 비밀을 안전하게 저장하는 데 한계가 있다는 것을 발견했습니다. 이러한 한계를 극복하기 위해 클라이언트 비밀 없이도 권한 부여 코드를 안전하게 교환할 수 있도록 하는 OAuth 확장인 PKCE(Proof Key for Code Exchange)를 소개했습니다.

우리의 제품인 Logto는 OAuth 및 OIDC 프로토콜의 모범 사례를 따르며, 공개 클라이언트의 보안을 보호하기 위한 PKCE 사용의 채택을 포함하여 각 단계에서 보안을 보장하는 종합적인 CIAM 솔루션입니다.