C++ Qt login an https server, no use connect

If you want to perform an HTTPS login in C++ with Qt, without using the connect mechanism (which is usually used for event-driven signal-slot communication), you can handle the network request synchronously or with a separate thread to avoid blocking the main thread.

You can use QNetworkAccessManager::get() or QNetworkAccessManager::post() to make the request. However, for this case, since you're handling the login with credentials, you'll probably need to make a POST request with the appropriate data. For synchronous communication, you can block the main thread and wait for the response.

Here's how you can do it synchronously without using connect:

Synchronous Example (Blocking Call):

复制代码

cpp

复制代码
`#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QSslConfiguration>
#include <QSslSocket>
#include <QJsonDocument>
#include <QJsonObject>
#include <QTimer>
#include <QEventLoop>
#include <QDebug>

int SGServerManage::LoginHttpsServerWithResponse(const QString& sUrl, const QString& sUser, const QString& sPassword, QString& sResponse, QString& sToken) {
    // Create a network manager instance
    QNetworkAccessManager networkManager(this);

    // Construct the URL and create a request
    QUrl qUrl(sUrl);
    QNetworkRequest request(qUrl);

    // Set content type header
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

    // Configure SSL settings for the request
    QSslConfiguration sslConfig = QSslConfiguration::defaultConfiguration();
    sslConfig.setProtocol(QSsl::TlsV1_2);  // Force TLS 1.2
    sslConfig.setPeerVerifyMode(QSslSocket::VerifyNone);  // Ignore SSL certificate verification (for self-signed certs)
    request.setSslConfiguration(sslConfig);

    // Set ciphers for the SSL connection
    QList<QSslCipher> ciphers;
    ciphers.append(QSslCipher("TLS_AES_128_GCM_SHA256"));
    ciphers.append(QSslCipher("TLS_AES_256_GCM_SHA384"));
    sslConfig.setCiphers(ciphers);
    request.setSslConfiguration(sslConfig);

    // Prepare the request body with the user credentials
    QJsonObject jsonBody;
    jsonBody["username"] = sUser;
    jsonBody["password"] = sPassword;

    QJsonDocument jsonDoc(jsonBody);
    QByteArray jsonData = jsonDoc.toJson(QJsonDocument::Compact);

    // Send the POST request and block until the response is received
    QNetworkReply* reply = networkManager.post(request, jsonData);

    // Wait for the request to finish (blocking)
    QEventLoop loop;
    connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
    loop.exec();  // This will block until the reply is finished

    // Handle the reply
    int result = -1;
    if (reply->error() != QNetworkReply::NoError) {
        qDebug() << "Error:" << reply->errorString();
        sToken.clear();
        sResponse = reply->errorString();
        result = -1;
    } else {
        QByteArray response = reply->readAll();
        qDebug() << "Response:" << response;
        sResponse = QString::fromUtf8(response);

        QJsonDocument jsonDoc = QJsonDocument::fromJson(response);
        if (jsonDoc.isObject()) {
            QJsonObject jsonObj = jsonDoc.object();

            if (jsonObj.contains("token")) {
                sToken = jsonObj["token"].toString();
                qDebug() << "Token:" << sToken;
                result = 0;
            } else {
                qDebug() << "Token not found in the response.";
                sToken.clear();
                result = -2;
            }
        } else {
            qDebug() << "Invalid JSON response.";
            sToken.clear();
            result = -3;
        }
    }

    // Clean up
    reply->deleteLater();

    return result;
}
`

cpp

Explanation:

  1. Blocking Behavior : Instead of using connect and asynchronous signal-slot connections, I used QEventLoop and connected the finished signal of the QNetworkReply to quit the loop. This makes the network request block until a response is received.

  2. POST Request : The request is sent using networkManager.post(request, jsonData), and the response is handled synchronously once it's finished.

  3. SSL Configuration : I've set the SSL configuration to enforce the use of TLSv1_2 and ignore SSL verification errors (QSslSocket::VerifyNone), which is commonly used when working with self-signed certificates. However, for production, you'd want to ensure proper SSL certificate validation.

  4. Event Loop : After sending the request, we wait for the response by using a QEventLoop. This blocks the thread until the finished signal is emitted, indicating the reply is complete.

Thread-Safety Considerations:

  1. Thread Blocking : This approach blocks the calling thread until the network request is finished. If this method is called from the main thread in a GUI application, the UI will freeze while waiting for the server's response. If you need to avoid this, consider moving the request to a worker thread (using QThread or QtConcurrent::run) and still handle it synchronously within that thread.

  2. Single Threaded Usage : If the QNetworkAccessManager is used in multiple threads, each thread should create its own instance of QNetworkAccessManager to ensure thread safety.

  3. GUI Freezing : If you use this in a GUI application, remember that the main thread will be blocked. To avoid this, you can either use asynchronous methods with connect or offload the work to a separate worker thread.

Moving to Asynchronous Handling (No connect)

If you don't want to use connect and still want to perform the task asynchronously, you can handle the response in a worker thread. This allows you to not block the UI while waiting for the response. Here's an example of how to do that:

复制代码

cpp

复制代码
`// Create a worker thread and run the network request asynchronously in that thread
`

Would you like an example of handling this in a worker thread or further explanation on that topic? Let me know!

相关推荐
凉茶钱1 小时前
红黑树:用“颜色”换“平衡”,set 与 map 的底层发动机
开发语言·c++·红黑树
octopus_c2 小时前
C++ 模板详解:函数模板、类模板、特化与分离编译
开发语言·c++·算法
東隅已逝,桑榆非晚2 小时前
算法1. 双指针法-移动零
c++·算法
李纲明3 小时前
WordPress 登录后跳回登录页或提示「Cookie 被阻止」:先核站点 URL 与 HTTPS 一致,再查安全插件与 CDN
https·登录·cdn·wordpress·cookie·devdiy·站点url
悠仁さん4 小时前
【C++】set map 使用
java·前端·c++
艾莉丝努力练剑4 小时前
【AI大模型接入SDK】ChatServer问题修复
c++·学习·ai·大模型·sdk
扶尔魔ocy5 小时前
【QT C++】常用设计模式
c++·设计模式
晚风予卿云月5 小时前
【C++高并发内存池】 2.ThreadCache设计
开发语言·c++·高并发内存池·tcmalloc
東隅已逝,桑榆非晚5 小时前
红黑树:从概念到实现
数据结构·c++·笔记·学习
艾莉丝努力练剑6 小时前
【AI大模型接入SDK】ChatServer接口测试
网络·c++·人工智能·学习·ai·大模型·sdk