qt https post TLS "Host requires authentication."
使用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;
}