使用qt開發一個https的登錄功能,總是提示我“Host requires authentication.”,已經安裝相關的教程將ssl的插件安裝好了。
設備的訪問的要求如下:
因要方位設備 IP 無法固定, https server 使用了自簽名的證書,因此在配置客戶端 http TLS 傳輸層引數時,需設定為忽略認證服務端的證書鏈和主機名(即接受服務端提供的任何證書和該證書中的任何主機名) 。
處理方法:
在訪問的時候已經設計為QueryPeer或VerifyNone,都沒有辦法解決這個問題。代碼如下,那位大神指點一下。
bool xx::login(string host, string username, string password, int timeout)
{
// 登錄地址https://{host}/login
QUrl loginulr(host.c_str());
loginulr.setScheme("https"); // 設定https訪問
loginulr.setPath("login"); // 設定路徑
QNetworkRequest request;
request.setUrl(loginulr);
request.setRawHeader("Accept", "application/json"); // Accept: 'application/json'
request.setRawHeader("Content-Type", "application/json"); // 'Content-Type': 'application/json'
QSslConfiguration config = QSslConfiguration::defaultConfiguration();
config.setPeerVerifyMode(QSslSocket::QueryPeer);
config.setProtocol(QSsl::AnyProtocol);
request.setSslConfiguration(config);
// 登錄資訊{"username":"demo","password":"demo"}
QJsonObject reqJson;
reqJson.insert("username", username.c_str());
reqJson.insert("password", password.c_str());
QNetworkReply *pReply = netmanager->post(request, QJsonDocument(reqJson).toJson().toStdString().c_str());
// 用于設定超時
QTimer timer;
timer.setInterval(timeout); // 設定超時時間,默認是10,000ms
timer.setSingleShot(true); // 單次觸發
// 設定處理事件
QEventLoop loop;
connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit);
connect(pReply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
timer.start();
loop.exec(); // 啟動事件回圈
// 處理登錄事件
if (timer.isActive()) { // 處理回應
timer.stop();
if (pReply->error() != QNetworkReply::NoError) {
//每次執行都會在此處回傳一個“Host requires authentication.”錯誤,不知道是什么原因
// 錯誤處理
LGlobalLogger::Instance().log(LLogger::MIError, "用戶:{%},回傳資料錯誤。{%}。", username, pReply->errorString().toStdString());
loginInfo.online = false; // 標記當前沒有登錄成功
} else {
QVariant variant = pReply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
int nStatusCode = variant.toInt();
cout << ":" << nStatusCode << endl;
// 如果成功的登錄了
if (nStatusCode == 200){
QByteArray bytes = pReply->readAll(); // 讀取回傳的json資料
QJsonDocument jsonDocument = QJsonDocument::fromJson(bytes.toStdString().data());
LGlobalLogger::Instance().log(LLogger::MIInfo,
jsonDocument.object().value("token").toString().toStdString()); // 資料寫入日志
if (jsonDocument.isNull()){
loginInfo.online = false; // 標記為沒有讀取成功
LGlobalLogger::Instance().log(LLogger::MIInfo, "用戶:{%},回傳資料錯誤。{%}。", username, bytes.toStdString());
} else {
loginInfo.online = true; // 標記為登錄成功
loginInfo.host = host;
loginInfo.username = username;
loginInfo.password = password;
loginInfo.updatetime = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count(); // 獲取當前的時間戳,ms
loginInfo.token = jsonDocument.object().value("token").toString().toStdString();
loginInfo.dispName = jsonDocument.object().value("User").toObject().value("displayName").toString().toStdString();
loginInfo.id = jsonDocument.object().value("User").toObject().value("id").toString().toStdString();
LGlobalLogger::Instance().log(LLogger::MIInfo, "用戶:{%},登錄成功。", username, nStatusCode);
}
}
// 登錄的用戶和密碼錯誤
if ((nStatusCode >= 400) && (nStatusCode <= 409)) {
loginInfo.online = false;
LGlobalLogger::Instance().log(LLogger::MIError, "用戶:{%},登錄失敗,錯誤代碼{%}。", username, nStatusCode);
}
// 服務器內部錯誤
if ((nStatusCode >= 500) && (nStatusCode <= 509)) {
loginInfo.online = false;
LGlobalLogger::Instance().log(LLogger::MIError, "用戶:{%},登錄失敗,錯誤代碼{%}。", username, nStatusCode);
}
pReply->deleteLater(); // 洗掉回傳的資料物件
// 將資料處理的連接重新建立
//connect(netmanager, &QNetworkAccessManager::finished, this, &Llzdiaio::replyFinished, Qt::QueuedConnection);
}
} else { // 處理超時
disconnect(pReply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
pReply->abort();
pReply->deleteLater();
loginInfo.online = false;
LGlobalLogger::Instance().log(LLogger::MIError, "用戶:{%},服務器沒有回應。", username);
}
return loginInfo.online;
}
uj5u.com熱心網友回復:
服務端是誰提供的?問他會更清楚吧 你先用工具試 如postman 介面能通了再來調代碼吧轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/271672.html
標籤:C++ 語言
上一篇:銀行系統開發
