如何使用 Qt oauth 创建登录页面?

2023-12-10

我一直在网上寻找如何在 Qt 桌面应用程序打开时创建身份验证页面。我已经构建了该应用程序;它非常小,仅由 main.cpp 调用的 MainWindow 组成。

现在我想在用户打开应用程序时添加一个身份验证页面。我创建了一个 Google API(按照此链接中的说明进行操作:http://blog.qt.io/blog/2017/01/25/connecting-qt-application-google-services-using-oauth-2-0/);但这确实是不完整的。在网上查找时,我找不到一个链接来提供一个有效的示例,其中: - 用户运行应用程序并被要求输入用户名和密码; - 如果它还不存在,他可以创建一个。

我发现的只是一段不完整的代码,就像我上面分享的链接一样;或教程,展示如何使用硬编码密码和用户名创建登录页面(这不是我想要的,我希望人们能够根据 Google API 动态添加自己)。

所以,如果有人有一小段代码,要求用户输入用户名和密码,并用该代码管理对 API 的请求,那就太好了!


编辑:添加我的代码

我正在添加我的类 GoogleGateway 的代码(受到我在这里发现的启发:如何使用 QOAuth2AuthorizationCodeFlow 和 QOAuthHttpServerReplyHandler 设置redirect_uri)

谷歌网关.h:

#ifndef GOOGLEGATEWAY_H
#define GOOGLEGATEWAY_H

#include <QObject>

class GoogleGateway : public QObject
{
    Q_OBJECT

public:
    GoogleGateway();
};

#endif // GOOGLEGATEWAY_H

谷歌网关.cpp:

#include "googlegateway.h"
#include <QApplication>
#include <QObject>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QString>
#include <QFile>
#include <QUrl>
#include <QOAuth2AuthorizationCodeFlow>
#include <QOAuthHttpServerReplyHandler>
#include <QDesktopServices>

GoogleGateway::GoogleGateway() :
    QObject(){

auto google = new QOAuth2AuthorizationCodeFlow;
google->setScope("email");

this->connect(google, &QOAuth2AuthorizationCodeFlow::authorizeWithBrowser, &QDesktopServices::openUrl);

QString val;
QFile file;
file.setFileName("/.../auth.json");
file.open(QIODevice::ReadOnly | QIODevice::Text);
val = file.readAll();
file.close();

QJsonDocument document = QJsonDocument::fromJson(val.toUtf8());
QJsonObject object = document.object();
const auto settingsObject = object["web"].toObject();
const QUrl authUri(settingsObject["auth_uri"].toString());
const auto clientId = settingsObject["client_id"].toString();
const QUrl tokenUri(settingsObject["token_uri"].toString());
const auto clientSecret(settingsObject["client_secret"].toString());
const auto redirectUris = settingsObject["redirect_uris"].toArray();
const QUrl redirectUri(redirectUris[0].toString());
const auto port = static_cast<quint16>(redirectUri.port());

google->setAuthorizationUrl(authUri);
google->setClientIdentifier(clientId);
google->setAccessTokenUrl(tokenUri);
google->setClientIdentifierSharedKey(clientSecret);

auto replyHandler = new QOAuthHttpServerReplyHandler(port, this);
google->setReplyHandler(replyHandler);

google->grant();

}

现在,我需要在 MainWindow.cpp 中做什么来提示将使用 GoogleGateway 类的登录页面? GoogleGateway 类看起来不错吗?或者我需要修改一些东西吗?

另外,我在 MainWindow 构造函数中创建了 GoogleGateway 类的实例。当我运行代码时,它会在 Chrome 中打开一个 Web 选项卡,但会抛出错误 400,显示“错误:redirect_uri_mismatch”。这意味着什么?

感谢您的帮助。


至此,Qt 博客的文章就基本完成了。您只需要连接granted之后发出信号并提出所需的请求。

请注意,Qt 博客中的 redirect_uri 中的 /cb 路径不再有效(文章大约一年前发布)。

注意:路径“/cb”在当前版本中是强制的 QOAuthHttpServerReplyHandler 实现。

因此,如果您在运行代码后看到来自 google 的访问错误,只需将redirect_uri 从那里复制粘贴到您配置的客户端的 GoogleConsole 授权重定向 URI 中即可。http://localhost-8080.com/

enter image description here

P.S.:不要忘记再次从控制台下载带有凭据的 json 文件。

此外,如果您想在授权后调用任何 Google API,您需要在 GoogleConsole 中为您的项目启用它们。要测试代码,只需启用Google+ API

enter image description here

就是这样。这是完整且有效的代码。 (在Linux和Qt 5.10上测试,目前没有Windows,无法在那里测试)

谷歌网关.h

#ifndef GOOGLEGATEWAY_H
#define GOOGLEGATEWAY_H

#include <QObject>
#include <QOAuth2AuthorizationCodeFlow>
#include <QNetworkReply>

class GoogleGateway : public QObject
{
    Q_OBJECT
public:
    explicit GoogleGateway(QObject *parent = nullptr);

private:
    QOAuth2AuthorizationCodeFlow * google;
};

#endif // GOOGLEGATEWAY_H

谷歌网关.cpp

#include "googlegateway.h"
#include <QObject>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QString>
#include <QFile>
#include <QDir>
#include <QUrl>
#include <QOAuthHttpServerReplyHandler>
#include <QDesktopServices>


GoogleGateway::GoogleGateway(QObject *parent) : QObject(parent)
{
    this->google = new QOAuth2AuthorizationCodeFlow(this);
    this->google->setScope("email");

    connect(this->google, &QOAuth2AuthorizationCodeFlow::authorizeWithBrowser, &QDesktopServices::openUrl);

    QByteArray val;
    QFile file;
    file.setFileName(QDir::toNativeSeparators("/full/path/client_secret_XXXXXXX.apps.googleusercontent.com.json"));
    if(file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        val = file.readAll();
        file.close();
    }


    QJsonDocument document = QJsonDocument::fromJson(val);
    QJsonObject object = document.object();
    const auto settingsObject = object["web"].toObject();
    const QUrl authUri(settingsObject["auth_uri"].toString());
    const auto clientId = settingsObject["client_id"].toString();
    const QUrl tokenUri(settingsObject["token_uri"].toString());
    const auto clientSecret(settingsObject["client_secret"].toString());

    const auto redirectUris = settingsObject["redirect_uris"].toArray();
    const QUrl redirectUri(redirectUris[0].toString());
    const auto port = static_cast<quint16>(redirectUri.port());

    this->google->setAuthorizationUrl(authUri);
    this->google->setClientIdentifier(clientId);
    this->google->setAccessTokenUrl(tokenUri);
    this->google->setClientIdentifierSharedKey(clientSecret);

    auto replyHandler = new QOAuthHttpServerReplyHandler(port, this);
    this->google->setReplyHandler(replyHandler);
    this->google->grant();

    connect(this->google, &QOAuth2AuthorizationCodeFlow::granted, [=](){
        qDebug() << __FUNCTION__ << __LINE__ << "Access Granted!";
        auto reply = this->google->get(QUrl("https://www.googleapis.com/plus/v1/people/me"));
        connect(reply, &QNetworkReply::finished, [reply](){
            qDebug() << "REQUEST FINISHED. Error? " << (reply->error() != QNetworkReply::NoError);
            qDebug() << reply->readAll();
        });
    });
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 Qt oauth 创建登录页面? 的相关文章

随机推荐

  • JQuery 查找并更改字符串的样式

    我需要编写一个函数 在 HTML 页面中的所有内容中搜索特定字符串 如果找到 则更改文本的颜色 这可能吗 Thanks 你可以这样做 CSS someclass color red JavaScript p contains yourstr
  • 如何将“System::String ^”转换为“TCHAR”?

    我问了一个问题here涉及 C 和 C 通信 问题解决了 但又引发了新的问题 这将返回一个字符串 C return Marshal PtrToStringAnsi decryptsn InpData 这需要一个 TCHAR C lpAlph
  • 数据库特定的迁移代码[重复]

    这个问题在这里已经有答案了 我正在创建一个需要在多个数据库下运行的应用程序 我目前在迁移中有一些代码 我只想在特定数据库 postgresql 和 mysql 下运行 有什么方法可以设置吗 谢谢 您的迁移可以访问数据库连接connectio
  • NSArray 后面的方括号索引是什么意思? [复制]

    这个问题在这里已经有答案了 浏览 iTunes U 开发适用于 iPhone 和 iPad 的 iOS 7 应用程序以及第 3 讲幻灯片中的第 120 页 有一个测验问题询问以下代码行的作用 说实话 我有点困惑 希望有人能破解它 cardA
  • “~”运算符在此脚本中做什么? [复制]

    这个问题在这里已经有答案了 您好 我从特定索引中删除一个数组 我附带了这个脚本 var arr 1 2 3 4 var index 2 if index arr splice index 1 我谷歌 what does operator d
  • 使用Spring SpEL表达式获取Annotation中引用的动态参数

    我想做的是拥有一个看起来很像 Spring 提供的 Cacheable Annotation 的注释 在方法之上使用 如下所示 CleverCache key orders concat id public Order getOrder i
  • 通过管道传递多个参数和最后一个函数的结果

    我正在使用 Ramda js 构建一个管道 它接受三个参数 第一个函数需要这三个参数 其结果用于第二个函数 但是 第二个函数还需要初始参数之一 我无法弄清楚构建类似的东西的分支 在伪代码风格中 我需要这样的东西 const composed
  • OAuth、带参数的 POST 问题

    我正在使用 Jon Crosby 的开源 Objective C OAuth 库http code google com p oauthconsumer 对于一些不处理令牌的基本 http 身份验证 仅处理消费者密钥和消费者秘密 我的代码非
  • 在 Blazor WebAssembly 应用程序中授权普通 Razor 页面?

    我正在使用 Blazor Wasm 编写 SPA 我使用了标准模板并包含托管在服务器中的用户帐户 该服务器也创建了服务器应用程序 到目前为止一切都很好 我想补充一点 我正在使用 Net5 RC2 但我认为这不是我的问题 我希望在服务器和客户
  • Weka GUI 和 Weka 通过 Java 代码得到不同的结果

    我正在使用 NaiveBayesMultinomialText 分类器在 Weka 中应用文本分类 问题是 当我使用 GUI 来执行此操作并在相同的列车数据上进行测试 无需交叉验证 时 我获得了 93 的准确率 而当我尝试通过 java 代
  • 使用maven将版本号输出到文本文件

    我想生成一个 zip 文件 该文件将使用 Maven 更新应用程序 该 zip 将托管在服务器上 我使用程序集插件来生成 zip 不过 我希望 maven 自动生成一个文本文件 将当前版本号存储在 zip 之外 这怎么可能 编辑 我使用 M
  • 使用 ggplot 实现多年销售的同步 X 轴

    我有从2012 01 01到现在 2015 11 20 的1417天的销售数据 我不知道如何在同一年的窗口中拥有单年 1月1日 12月31日 轴和每年的销售额 即使使用ggplot scolor as factor Year option
  • 在不使用 SQLAlchemy 的情况下在 Flask 工厂函数中配置 MySQL 数据库

    我是 Flask 新手 正在尝试使用 MySQL 数据库构建一个简单的应用程序 但是 我不想使用 SQLAlchemy 相反 我想使用mysql connector并将 SQL 语句定向到数据库中的 SELECT INSERT UPDATE
  • 使用 CMake 和 Conan 的外部库的未定义引用

    我正在尝试开发一个程序 使用 Conan 和 CMake 以及 LibLogicalAccess 库与 PCSC USB 读卡器进行通信 我按照构建和安装库的说明进行操作 似乎进展顺利 我使用 main cpp 文件创建了一个小型简单的控制
  • 如何在将上传的文件保存到目录之前重命名它?

    下面是我用来将文件上传到目录的代码 效果很好 我的主要问题是 move uploaded file 就是将上传的文件保存到目录中的 也是我猜测的move uploaded file 是为其设置名称的人 如何将文件名更改为随机数 我尝试在下面
  • 问号和冒号(?:三元运算符)在 Objective-C 中意味着什么?

    这行代码是什么意思 label frame inPseudoEditMode kLabelIndentedRect kLabelRect The and 让我困惑 这是C三元运算符 Objective C 是 C 的超集 label fra
  • 八度舍入和评估顺序

    在八度我得到 1 0 05 0 95 0 and 1 0 95 0 05 4 1633e 17 据我所知 这是由求值顺序与近似二进制表示相结合引起的 0 05 为 0 00 0011 和 0 95 为 0 11 1100 有人可以给我整个故
  • mailto 与 Dojo 一起使用时导致 IE8 中出现空白页面

    由于某种原因 在 IE 中 准确地说是 Win 7 中的 IE8 当我单击 mailto 链接时 最终当前页面被地址栏中带有 mailto 的空白页面替换 具体来说 当我单击 mailto 链接时会发生以下情况 新的 about blank
  • icCube - 如何使用 Apache Web 服务器对 icCube 进行身份验证

    我目前正在编写一个 Web 应用程序来访问我们 ICCube 系统的报告 应用程序页面托管在与 IcCube 服务器不同的服务器上 该服务器当前是本地 Apache 服务器 xampp 使用基本身份验证对用户进行身份验证 然后他们才能访问我
  • 如何使用 Qt oauth 创建登录页面?

    我一直在网上寻找如何在 Qt 桌面应用程序打开时创建身份验证页面 我已经构建了该应用程序 它非常小 仅由 main cpp 调用的 MainWindow 组成 现在我想在用户打开应用程序时添加一个身份验证页面 我创建了一个 Google A