本页内容

QOAuth2DeviceAuthorizationFlow Class

QOAuth2DeviceAuthorizationFlow 类提供了设备授权授予流程的实现。更多内容...

头文件: #include <QOAuth2DeviceAuthorizationFlow>
CMake: find_package(Qt6 REQUIRED COMPONENTS NetworkAuth)
target_link_libraries(mytarget PRIVATE Qt6::NetworkAuth)
qmake: QT += networkauth
自: Qt 6.9
继承自: QAbstractOAuth2

属性

公共函数

QOAuth2DeviceAuthorizationFlow()
QOAuth2DeviceAuthorizationFlow(QObject *parent)
QOAuth2DeviceAuthorizationFlow(QNetworkAccessManager *manager, QObject *parent = nullptr)
virtual ~QOAuth2DeviceAuthorizationFlow() override
QUrl completeVerificationUrl() const
bool isPolling() const
QString userCode() const
QDateTime userCodeExpirationAt() const
QUrl verificationUrl() const

公共槽位

virtual void grant() override
bool startTokenPolling()
void stopTokenPolling()

信号

void authorizeWithUserCode(const QUrl &verificationUrl, const QString &userCode, const QUrl &completeVerificationUrl)
void completeVerificationUrlChanged(const QUrl &completeVerificationUrl)
void pollingChanged(bool polling)
void userCodeChanged(const QString &userCode)
void userCodeExpirationAtChanged(const QDateTime &expiration)
void verificationUrlChanged(const QUrl &verificationUrl)

受保护的插槽

(since 6.9) void refreshTokensImplementation()

详细说明

该类实现了设备授权授予流程,用于获取和刷新访问令牌及身份令牌,特别适用于缺少用户代理或输入功能受限的设备。此类设备包括电视、机器人机界面(HMI)、家用电器和物联网设备。

设备授权授予流程可在任何支持 SSL/TLS 请求的平台和操作系统上使用。与QOAuth2AuthorizationCodeFlow 不同,该流程不基于重定向,因此不使用reply handler 。

设备流的使用

以下代码片段展示了典型的使用方式。首先,我们按照与QOAuth2AuthorizationCodeFlow 类似的方式设置该流程:

m_deviceFlow.setAuthorizationUrl(QUrl(authorizationUrl));
m_deviceFlow.setTokenUrl(QUrl(accessTokenUrl));
m_deviceFlow.setRequestedScopeTokens({scope});
m_deviceFlow.setClientIdentifier(clientIdentifier);
// The need for a client secret depends on the authorization server
m_deviceFlow.setClientIdentifierSharedKey(clientSecret);

然后,我们将该流程连接到authorizeWithUserCode 信号,以处理用户授权:

connect(&m_deviceFlow, &QOAuth2DeviceAuthorizationFlow::authorizeWithUserCode, this,
    [](constQUrl&verificationUrl, constQString&userCode, constQUrl&completeVerificationUrl) {
        if(completeVerificationUrl.isValid()) {
            // 如果授权服务器提供了一个完整的 URL,
            // 且该 URL 参数中已包含必要数据,
            // 则可以选择使用该 URL
            qDebug() << "Complete verification uri:" << completeVerificationUrl;
        }else{
            // 授权服务器仅提供了验证 URL;使用该 URL
            qDebug() << "Verification uri and usercode:" << verificationUrl << userCode;
        }
    }
);

这一部分对整个流程至关重要,具体如何处理取决于您的具体使用场景。无论采取何种方式,用户都需要完成授权。

设备流程并未规定授权完成的具体方式,因此能够灵活适应不同的使用场景。这可以通过向用户显示验证 URI 和用户代码来实现,用户随后可在另一台设备上访问该链接。 此外,您还可以向用户展示二维码供其使用移动设备扫描、发送至配套应用程序、通过电子邮件发送给用户等。

在授权待处理期间,QOAuth2DeviceAuthorizationFlow 会以特定间隔(通常为 5 秒)轮询服务器,直到用户接受或拒绝授权为止;此时服务器将作出相应响应,流程随即结束。

错误可按以下方式检测:

connect(&m_deviceFlow, &QAbstractOAuth::requestFailed, this, [](QAbstractOAuth::Error error) {
    Q_UNUSED(error);
    // Handle error
});

connect(&m_deviceFlow, &QAbstractOAuth2::serverReportedErrorOccurred, this,
    [](const QString &error, const QString &errorDescription, const QUrl &uri) {
        // Check server reported error details if needed
        Q_UNUSED(error);
        Q_UNUSED(errorDescription);
        Q_UNUSED(uri);
    }
);

QAbstractOAuth2::serverReportedErrorOccurred() 信号可用于获取特定 RFC 定义的错误信息。但是,与QAbstractOAuth::requestFailed() 不同,它不涵盖网络错误或客户端配置错误等错误。

流完成的检测方式与QOAuth2AuthorizationCodeFlow 类似,例如:

connect(&m_deviceFlow, &QAbstractOAuth::granted, this, [this](){
    // Here we use QNetworkRequestFactory to store the access token
    m_api.setBearerToken(m_deviceFlow.token().toLatin1());
});
m_deviceFlow.grant();

属性文档

[read-only] completeVerificationUrl : QUrl

该属性包含一个用于用户完成授权的 URL。该 URL 本身包含user_code ,因此用户无需手动输入该代码。不同授权服务器对该完整 URL 的支持情况各不相同。

访问函数:

QUrl completeVerificationUrl() const

通知信号:

void completeVerificationUrlChanged(const QUrl &completeVerificationUrl)

另请参阅 verificationUrl 和Device Flow Usage 。

[read-only] polling : bool

该属性表示流是否正在主动轮询令牌。

访问函数:

bool isPolling() const

通知器信号:

void pollingChanged(bool polling)

另请参阅 startTokenPolling() 和stopTokenPolling()。

[read-only] userCode : QString

该属性存储授权响应中收到的user_code。用户需使用此代码来完成授权。

访问函数:

QString userCode() const

通知信号:

void userCodeChanged(const QString &userCode)

另请参阅 verificationUrl 、completeVerificationUrl 以及Device Flow Usage 。

[read-only] userCodeExpirationAt : QDateTime

该属性存储用户代码和底层设备代码过期时的本地时间。这些代码的有效期通常在5到30分钟之间。

访问函数:

QDateTime userCodeExpirationAt() const

通知信号:

void userCodeExpirationAtChanged(const QDateTime &expiration)

另请参阅 userCode 。

[read-only] verificationUrl : QUrl

该属性存储用户应输入用户代码以完成授权的 URL。

访问函数:

QUrl verificationUrl() const

通知信号:

void verificationUrlChanged(const QUrl &verificationUrl)

另请参阅 userCode 、completeVerificationUrl 以及Device Flow Usage 。

成员函数文档

QOAuth2DeviceAuthorizationFlow::QOAuth2DeviceAuthorizationFlow()

创建一个 QOAuth2DeviceAuthorizationFlow 对象。

[explicit] QOAuth2DeviceAuthorizationFlow::QOAuth2DeviceAuthorizationFlow(QObject *parent)

创建一个 QOAuth2DeviceAuthorizationFlow 对象,其父对象为parent 。

[explicit] QOAuth2DeviceAuthorizationFlow::QOAuth2DeviceAuthorizationFlow(QNetworkAccessManager *manager, QObject *parent = nullptr)

使用parent 作为父对象构建一个QOAuth2DeviceAuthorizationFlow对象,并将manager 设置为网络访问管理器。

[override virtual noexcept] QOAuth2DeviceAuthorizationFlow::~QOAuth2DeviceAuthorizationFlow()

销毁QOAuth2DeviceAuthorizationFlow 实例。

[signal] void QOAuth2DeviceAuthorizationFlow::authorizeWithUserCode(const QUrl &verificationUrl, const QString &userCode, const QUrl &completeVerificationUrl)

当用户需要完成授权时,会发出此信号。

如果授权服务器提供了completeVerificationUrl ,用户可以导航至该 URL。该 URL 包含所需的userCode 以及任何其他必需的参数。

或者,用户需要访问verificationUrl 并手动输入userCode 。

另请参阅 Device Flow Usage 。

[override virtual slot] void QOAuth2DeviceAuthorizationFlow::grant()

重写了:QAbstractOAuth::grant()。

启动《设备授权 RFC》中所述的授权流程。

该流程包括以下步骤:

该流程会自动从授权阶段过渡到令牌轮询阶段。

调用此函数将重置任何先前的授权数据。

另请参阅 authorizeWithUserCode()、granted()、QAbstractOAuth::requestFailed()、polling 、startTokenPolling()、stopTokenPolling() 和Device Flow Usage 。

[protected slot, since 6.9] void QOAuth2DeviceAuthorizationFlow::refreshTokensImplementation()

此函数发送令牌刷新请求。

如果刷新请求成功发起,状态将设置为QAbstractOAuth::Status::RefreshingToken ;否则将发出requestFailed()信号,且状态保持不变。当isPolling 的值为true 时,无法刷新令牌。

如果令牌刷新过程已经在进行中,则此函数无效。

如果令牌刷新失败且存在访问令牌,则状态将设置为QAbstractOAuth::Status::Granted ;如果不存在访问令牌,则状态将设置为QAbstractOAuth::Status::NotAuthenticated 。

此函数在 Qt 6.9 中引入。

另请参阅 QAbstractOAuth::requestFailed() 和QAbstractOAuth2::refreshTokens()。

[slot] bool QOAuth2DeviceAuthorizationFlow::startTokenPolling()

开始令牌轮询。如果启动成功(或轮询已处于活动状态),则返回true ;否则返回false 。

在典型用例中无需调用此函数。一旦授权请求通过调用 `grant()` 完成,轮询将自动启动。

当需要在稍后时间恢复(重试)令牌轮询,而无需重启整个授权流程时,此函数会非常有用。例如,在发生短暂的网络连接中断时。

轮询间隔由授权服务器定义,通常为 5 秒。第一个轮询请求将在第一个间隔结束后发送。

另请参阅 polling 、stopTokenPolling() 以及Device Flow Usage 。

[slot] void QOAuth2DeviceAuthorizationFlow::stopTokenPolling()

停止令牌轮询。任何潜在的未处理轮询请求都将被静默丢弃。

另请参阅 polling 和startTokenPolling()。

© 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.