이 페이지에서

Qt OAuth2 브라우저 지원

OAuth2 사용자 에이전트

OAuth2 인증 단계는 사용자 에이전트에 의존하며, 이는 일반적으로 시스템 브라우저나 다음과 같은 내장형 사용자 에이전트입니다 Qt WebEngine.

시스템 브라우저와 내장형 사용자 에이전트 중 어느 것을 선택할지는 여러 요인에 따라 달라집니다. 다음은 몇 가지 주요 고려 사항입니다:

  • 시스템 브라우저에는 이미 사용자의 로그인 상태가 유지되어 있을 수 있습니다. 따라서 기존 로그인 정보를 활용할 수 있으므로 인증 단계에서의 사용자 인증이 더 간편할 수 있습니다. 반면 내장형 사용자 에이전트의 경우, 사용자는 일반적으로 새로 로그인해야 합니다. 반면, 시스템 브라우저에 로그인 세션을 그대로 두는 것이 항상 바람직하지는 않을 수 있습니다. 또한 시스템 브라우저는 애플리케이션 사용 데이터를 다른 당사자와 공유할 수도 있습니다.
  • 시스템 브라우저는 일반적으로 사용자에게 친숙하며, 로그인 시 익숙한 사용자 경험을 제공합니다. 반면, 내장형 사용자 에이전트는 익숙하지 않은 외관과 느낌을 제공할 수 있지만, 애플리케이션 개발자는 별도의 브라우저 창에서 로그인 상호작용이 이루어지는 대신 이를 애플리케이션 창 일부로 통합할 수 있습니다. 또한 애플리케이션 개발자는 더 이상 필요하지 않을 때 내장형 사용자 에이전트의 종료를 자동화할 수 있습니다.
  • 시스템 브라우저는 주소 표시줄이나 인증서 유효성 검사 등 사용자에게 친숙한 보안 시각적 요소를 제공합니다. 이러한 요소들은 내장형 사용자 에이전트에서는 표시되지 않을 수 있습니다. 또한 시스템 브라우저는 기본 운영 체제의 보안 기능을 더 잘 활용할 수 있습니다.
  • 임베디드 사용자 에이전트는 사용자가 입력하는 모든 보안 인증 정보에 접근할 가능성이 있습니다.
  • 모든 플랫폼이 https 또는 사용자 정의 URI 스키마 리디렉션 URL( QOAuthUriSchemeReplyHandler 참조) 처리를 지원하는 것은 아닙니다. 이러한 플랫폼의 경우, 내장형 사용자 에이전트를 사용하여 이러한 제한을 우회할 수 있습니다.
  • 애플리케이션의 일부로 내장형 사용자 에이전트를 포함하는 것은 일반적으로 큰 구성 요소가 되어 애플리케이션의 저장 공간 사용량을 증가시킵니다. 반면, 모든 사용 사례에서 시스템 브라우저를 사용할 수 있는 것은 아니며, 애플리케이션이 이미 다른 목적으로 내장형 사용자 에이전트를 사용하고 있을 수도 있습니다.

이러한 점을 고려할 때, 네이티브 애플리케이션의 경우 시스템 브라우저를 사용하는 것이 권장됩니다. 하지만 앞서 언급한 몇 가지 사항에서 암시된 바와 같이, 내장형 사용자 에이전트를 사용해야 할 타당한 사용 사례가 여전히 존재할 수 있습니다.

시스템 브라우저 사용

시스템 브라우저를 사용하려면 브라우저를 열고 애플리케이션에서 구성한 인증 URL로 이동해야 합니다. 일반적인 사용 방법은 다음과 같습니다:

connect(&m_oauth, &QAbstractOAuth::authorizeWithBrowser, this, &QDesktopServices::openUrl);

이 코드는 QAbstractOAuth::authorizeWithBrowser 신호와 QDesktopServices::openUrl 슬롯을 연결합니다. 이렇게 하면 시스템 브라우저가 열리고, 사용자는 해당 브라우저에서 필요한 인증 및 권한 부여 절차를 수행합니다. 애플리케이션이나 Qt 라이브러리는 시스템 브라우저를 직접 제어할 수 없으며, 일반적으로 권한 부여가 완료되면 브라우저는 열린 상태로 유지됩니다.

시스템 브라우저와 관련된 자세한 내용 및 지원되는 리디렉션 URL 스키마에 대해서는 OAuth 2.0 개요( QOAuthHttpServerReplyHandler) 및 QOAuthUriSchemeReplyHandler 을 참조하십시오.

다음 기능을 사용하면 Qt WebEngine

Qt WebEngine 는 웹 콘텐츠를 Qt 애플리케이션에 직접 삽입할 수 있는 웹 브라우저 엔진을 제공합니다.

핵심 제어 기능과 함께, QtWidgets 및 QtQuick 애플리케이션 모두에서 사용하기 쉬운 뷰가 제공됩니다. 이러한 뷰는 OAuth2 인증에서 사용자 에이전트로 사용될 수 있습니다. Qt WebEngine 는 규모가 크고 다재다능한 모듈이며, 이 문서는 OAuth2 인증과 함께 사용하는 방법에 중점을 둡니다.

Qt WebEngine 를 애플리케이션의 일부로 임베드하는 방법에는 여러 가지가 있습니다. 실용적인 관점에서 고려해야 할 주요 사항은 다음과 같습니다.

  • QtQuick 대 QtWidgets 애플리케이션. 이는 QtNetworkAuth 클래스와의 필수 통합을 설정하는 방법에 영향을 미칩니다.
  • 리디렉션 URI 스키마. 이는 어떤 QtNetworkAuth 응답 핸들러 클래스를 어떻게 사용할지에 영향을 미칩니다( OAuth 2.0 개요 참조).

QtQuick 및 QtWidgets 애플리케이션

Qt WebEngine 는 OAuth 2.0 인증을 위해 QtQuick 및 QtWidgets 애플리케이션 모두에서 사용할 수 있습니다. 주요 차이점은 몇 가지 필수 활성화 요소를 설정하는 방식에 있습니다.

다음은 간소화된 QWebEngineView (QtWidget) 설정 예시입니다. 오류 처리 및 잠재적인 Qt WebEngine 설정은 간결성을 위해 생략되었습니다.

다음과 같은 위젯이 있다고 가정합니다.

QWebEngineView *webView = nullptr;
QMainWindow mainWindow;

시스템 브라우저를 여는 대신, QWebEngineView 를 사용하여 인증을 수행합니다:

connect(&m_oauth, &QAbstractOAuth::authorizeWithBrowser, this, [this](const QUrl &url) {
    mainWindow.show();
    webView->load(url);
    webView->show();
});

인증 절차가 완료되면 뷰를 닫습니다:

connect(&m_oauth, &QAbstractOAuth::granted, this, [this]() {
    // Here we use QNetworkRequestFactory to store the access token
    m_api.setBearerToken(m_oauth.token().toLatin1());
    m_handler->close();
    webView->close();
});

QtQuick 애플리케이션의 경우 흐름은 원칙적으로 동일하지만, QWebEngineView 위젯 대신 WebEngineView QML 요소를 사용합니다:

WebEngineView {
    id: authorizationWebView
    anchors.fill: parent
    visible: false
}

이 단순화된 예제는 C++ 클래스에서 필요한 API를 노출합니다.

class HttpExample : public QObject
{
    Q_OBJECT
#ifdef QT_QML_LIB
    QML_NAMED_ELEMENT(OAuth2)
#endif
public:
    Q_INVOKABLE void authorize();

signals:
    void authorizationCompleted(bool success);
    void authorizeWithBrowser(const QUrl &url);

이 API들은 이후 QML 측에서 WebEngineView 를 호출하여 인증을 처리하는 데 사용됩니다:

onAuthorizeWithBrowser:
    (url) => {
        console.log("Starting authorization with WebView")
        authorizationWebView.url = url
        authorizationWebView.visible = true
    }
onAuthorizationCompleted:
    (success) => {
        console.log("Authorized: " + success);
        authorizationWebView.visible = false
    }

리디렉션 URI 스키마

리디렉션 URI 스키마(http, https 또는 custom-uri 스키마)의 선택은 Qt WebEngine.

http 루프백 URI

http 루프백 리디렉션 URI와 QOAuthHttpServerReplyHandler 을 사용할 경우, 처리 방식은 시스템 브라우저와 유사합니다. Qt WebEngine 은 시스템 브라우저와 마찬가지로 인증 요청을 리플라이 핸들러의 localhost 서버로 리디렉션합니다.

사용자 정의 스킴 URI

사용자 정의 스키마 URI(예: com.example.myqtapp:/redirect) 및 QOAuthUriSchemeReplyHandler 의 경우에도 흐름은 시스템 브라우저와 유사하게 작동합니다.

주요 차이점은 QOAuthUriSchemeReplyHandler 문서에 설명된 대로, iOS/macOS의 유니버설 링크(Universal Links )나 Android의 앱 링크(App Links)와 같이 애플리케이션을 별도로 구성할 필요가 없다는 점입니다.

m_handler.setRedirectUrl(QUrl{"com.example.myqtapp://oauth2redirect"_L1});
m_oauth.setReplyHandler(&m_handler);

connect(&m_oauth, &QAbstractOAuth::authorizeWithBrowser, this, [this](const QUrl &url) {
    mainWindow.show();
    webView->load(url);
    webView->show();
});
connect(&m_oauth, &QAbstractOAuth::granted, this, [this]() {
    // Here we use QNetworkRequestFactory to store the access token
    m_api.setBearerToken(m_oauth.token().toLatin1());
    m_handler.close();
    webView->close();
});

기술적으로 이 기능은 다음과 같이 작동합니다. Qt WebEngine 처리되지 않은 URI 스키마에 대해 QDesktopServices::openUrl()를 호출하며, 이에 대응하는 QOAuthUriSchemeReplyHandler 가 이를 수신 대기합니다.

https URI

https URI와 QOAuthUriSchemeReplyHandler 의 경우 로직이 약간 달라집니다. 사용자 정의 스킴 URI와 마찬가지로 애플리케이션을 별도로 구성할 필요는 없지만, 인증 단계의 마지막에 웹 엔진으로의 리디렉션을 제공해야 합니다.

connect(webView, &QWebEngineView::urlChanged, this, [this](const QUrl &url){
    m_handler.handleAuthorizationRedirect(url);
});

이 작업이 필요한 이유는 Qt WebEngine 리디렉션 URL은 유효한 https URL이므로, 기본적으로 해당 주소로 이동을 시도하기 때문입니다.

이러한 이동 시도를 방지하고, 의도치 않은 인증 코드 유출을 막기 위해(리디렉션 URL 도메인이 사용자의 통제 범위에 속하지 않는 경우를 고려해 보십시오), 보다 정교한 필터링을 적용해야 합니다. 또한 QOAuth2AuthorizationCodeFlow::PkceMethod 의 사용은 인증 코드 탈취의 영향을 완화하므로 강력히 권장됩니다.

예를 들어:

connect(webView->page(), &QWebEnginePage::navigationRequested,
        this, [this](QWebEngineNavigationRequest &request) {
    if (request.navigationType() == QWebEngineNavigationRequest::RedirectNavigation
        && m_handler.handleAuthorizationRedirect(request.url())) {
        request.reject();
        webView->close();
    } else {
        request.accept();
    }
});

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.