在平时上网时,我们登陆一些网站后,为了校验客户端的身份、保障数据的安全性,服务器会给浏览器发送一个token值,这个token值就是一张令牌,你可以把它看成一张通行证,有了它你才能对该网站进行提交数据、查询数据等操作,并且很大程度上,它能保障客户端与服务器数据连接的安全性。

一般(多数)情况下,token值都是有期限的,也就是它在一定时间内有效,超过这个设定时间,就需要重新获取新的token值。当然,也有无状态的token,它可以允许你在多个服务间共享。

原理

1、登陆获取token

(图源自互联网,若有侵权,请告知删除)

在QT模拟网页进行登陆操作时,无论是用get或POST方式,登陆成功之后,需要将服务器返回的token值保存下来,以便后面使用。以上一篇文章QT客户端与JAVA服务器的HTTPS通信为例,这里仅写一下关于token获取部分,相信熟悉QT操作JSON数据的同学,这点是非常简单的,其他代码可以参考该例子。void Widget::finishedSlot_Registered(QNetworkReply *registered)

{

if (registered->error() == QNetworkReply::NoError)

{

// 获取响应信息

QByteArray bytes = registered->readAll(); //读取所有字节;

QJsonParseError jsonError;

//转化为JSON文档

QJsonDocument doucment = QJsonDocument::fromJson(bytes, &jsonError);

// 解析Json error

if (doucment.isObject()) {

QJsonObject obj = doucment.object();

QJsonValue val;

QJsonValue data_value;

//解析Json对象

if(data_obj.contains("token")) //获取用户登陆的token

{

token_val = data_obj.value("token");

qDebug() << tr("打印token");

qDebug() << token_val;

}

if(data_obj.contains("username")) //获取用户名;

{

username = QString(data_obj.value("username").toString());

ui->textBrowser->appendPlainText(tr("登陆用户名为:")+username);

qDebug() << tr("打印username");

qDebug() << username;

}

if (data_obj.contains("user_id")) { //获取用户登陆ID

userid =QString::number(data_obj.value("user_id").toInt());

ui->textBrowser->appendPlainText(tr("登陆用户ID为:")+userid);

qDebug() << tr("打印userid");

qDebug() << userid;

}

}

}

}

这里关键是获取到服务器返回的token值

2、业务请求

(图源自互联网,若有侵权,请告知删除)

成功登陆拿到token 之后,后面所有的请求操作,都必须带上该token值,否则服务器会拒绝连接。那么,在QT中该如何带上token值呢?其实原理跟网页上的请求是一样的,带在请求头部。

示例:...

QString Url_serial = "https://www.example/api/";

QUrl serviceUrl(Url_serial);

QNetworkRequest request_registered(serviceUrl);

// 设置SSL认证方式

QSslConfiguration sslconfig;

sslconfig.setPeerVerifyMode(QSslSocket::VerifyNone);

sslconfig.setProtocol(QSsl::TlsV1_2);

//sslconfig.setPeerVerifyDepth(1);

//设置本地证书

QFile keyFile("client.p12");

bool openOK = keyFile.open(QIODevice::ReadWrite);

QSslKey key;

QSslCertificate certs;

QList caCerts;

QByteArray passPhrase = QString("12345678").toLatin1();

openOK = QSslCertificate::importPkcs12(&keyFile, &key, &certs, &caCerts, passPhrase);

keyFile.close();

request_registered.setSslConfiguration(sslconfig);

request_registered.setRawHeader("Accept","*/*");

request_registered.setRawHeader("Connection","keep-alive");

//设置 token 登陆凭证;

request_registered.setRawHeader(QByteArray("Authorization"),QByteArray(getQJsonDocumentFromQJsonValue(token_val)));

request_registered.setHeader(QNetworkRequest::UserAgentHeader,"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.152 Safari/537.36");

request_registered.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");

//组装数据

QUrlQuery postData1;

QByteArray serial_check1((char*)Serial_num, 16);

serial_check = serial_check1.toHex();

postData1.addQueryItem("seq",serial_check);

qDebug() << tr("提交的用户token:") + getQJsonDocumentFromQJsonValue(token_val);

//发起网络请求

QNetworkReply* check = m_accessManager_Registered->post(request_registered,postData1.toString(QUrl::FullyEncoded).toUtf8());

....

比较容易犯错的地方是request_registered.setRawHeader(QByteArray("Authorization"),QByteArray(getQJsonDocumentFromQJsonValue(token_val))) 中,第二个参数的值,也就是携带的token必须是QByteArray类型,而从服务器获取到的是JSON类型,所以需要做一个转换;

转换Demo示例:QByteArray Widget::getQJsonDocumentFromQJsonValue(QJsonValue jsonString)

{

QByteArray authon;

QJsonValue vals = jsonString;

if(vals.isObject())

{

QJsonDocument doc(vals.toObject());

authon = doc.toBinaryData();

}

else

{

authon = vals.toString().toUtf8();

}

return authon;

}

这样,就完成了一次携带token值的业务数据请求,后面所有的操作都需要携带这个。建议把它封装在请求头的类里面,方便可以直接使用。

Token过期,刷新Token

(图源自互联网,若有侵权,请告知删除)

前面提到,如果超出设定时间,token值已经过期了,那就无法进行操作了,这时就需要用户重新登陆,获取一个新的token值,这一步可以写在网络请求的响应函数里,通过服务器返回的JSON字段进行判断,如果服务器判定为token过期,那么就重新跳转到登陆,进行登陆操作,同时务必要清空保存token值的变量,对它重新赋值,以保证它是最新的。

总结

这篇文章讲到如何保存、转化和携带token值进行网络请求的操作,在QT网络编程中,这不算很难的知识点,但是确很容易出错,谨以此文章做为笔记,也希望能够帮助因此困惑的人,如果本文给您带来帮助,欢迎点赞,评论,转发,打赏。

——The End版权属于:编码书生

所有原创文章采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可。

除特别注明,您可以自由的转载和修改,但请务必注明文章来源且不可用于商业目的。

Qt登录服务器验证,QT笔记:QT模拟网页交互过程中的token验证机制相关推荐

  1. php sawgger token验证,Swagger中添加Token验证

    Swagger中添加Token验证 Swagger中添加Token验证 平常做项目使用mvc+webapi,采取前后端分离的方式,后台提供API接口给前端开发人员.这个过程中遇到一个问题后台开发人员怎 ...

  2. 一次性说清楚秒验(本机号码一键登录)基本原理、优势、场景、交互过程和常见的问题

    一. 关于秒验(一键登录)基本原理 秒验(一键登录)产品整合了三大运营商特有的数据网关认证能力,升级短信验证码体验,应用于用户注册.登陆.支付.安全校验等场景,可实现用户无感知校验,操作更安全.便捷. ...

  3. webapi中使用token验证(JWT验证)

    转自:https://www.cnblogs.com/ye-hcj/articles/8151385.html 本文介绍如何在webapi中使用JWT验证 准备 安装JWT安装包 System.Ide ...

  4. 华为云计算IE面试笔记-FusionSphere Openstack规划设计过程中要考虑哪些网络平面,各平面主要走哪些业务?

    在FusionSphere Openstack规划设计的过程中,至少有8个平面. 1. Internal_base,内部平面. ①是FusionSphere Openstack中的组件之间进行通信的网 ...

  5. token验证_Swagger中添加Token验证

    平常做项目使用mvc+webapi,采取前后端分离的方式,后台提供API接口给前端开发人员.这个过程中遇到一个问题后台开发人员怎么提供接口说明文档给前端开发人员.为了解决这个问题,项目中引用swagg ...

  6. 动态域名解析服务器离线会引起什么_动态域名解析过程中可能出现的问题及解决方案...

    动态域名在企业中应用非常广泛,金万维动态域名作为一款平稳运行10余年的软件,已是被业界所熟知.该系统由两部分构成,一部分是客户端,运行在用户的主机上:另一部分是服务器,由金万维负责运行. 谓动态域名解 ...

  7. java证书验证失败_Java 跳过 HTTPS 请求过程中证书验证问题

    受益于谷歌和苹果对 HTTPS 的强制升级要求,服务已经全面升级了,安全性提高的同时也引起了新的问题. 由于 HTTPS 证书还是很贵的,所以各种测试环境上各种非法证书,通过浏览器访问的时候可以直接选 ...

  8. Kubernetes--学习笔记-4-Kubernetes 集群搭建过程中常用命令

    一,查看版本信息 检查错误日志 journalctl -xe tail -f /var/log/messages 查看某个pod详细 kubectl describe pods/<pod名称&g ...

  9. 鸿钧老祖 数据结构笔记01:编程面试过程中常见的10大算法(java)

    以下是在编程面试中排名前10的算法相关的概念,我会通过一些简单的例子来阐述这些概念.由于完全掌握这些概念需要更多的努力,因此这份列表只是作为一个介绍.本文将从Java的角度看问题,包含下面的这些概念: ...

最新文章

  1. 训练三层BP神经网络实现异或运算 Python 代码实现
  2. ARM CPU分析(一) 指令集
  3. [Android]关于Root
  4. java阅读题_java 练习题带答案
  5. Ubuntu20.04上安装部署Elasticsearch
  6. 文献记录(part16)--Learning Bayesian Network Classifiers: Searching in a Space of Partially ...
  7. Codeforces Round #709 (Div. 1) C. Skyline Photo dp + 单调栈优化
  8. mysql 横向分表合并_MySQL横向扩展-分库分表解决方案总结
  9. 基于JAVA语言的selenium测试基础总结
  10. 【POJ2826】An Easy Problem?!(线段相交+分情况讨论+精度)
  11. 思科网络设备命令大全
  12. biu~biu~常用网站
  13. 计算机病毒是指______.,计算机病毒是指
  14. JS找出数组中重复的数字
  15. R语言安装NLP自然语言分析包
  16. SpringBoot中的SearchStrategy介绍
  17. CDH安装时报错:/opt/cloudera/parcels/.flood/.../CDH-6.3.2-1.cdh6.3.2.p0.1605554-el7.parcel does not exist
  18. 【Unity2D】制作可以左右移动的平台
  19. 对cross-env的理解
  20. 如果做好一个管理者的反思

热门文章

  1. 新加坡抢跑 Web3 战略高地,中国影子无处不在
  2. 基于二阶锥规划的主动配电网最优潮流求解(Matlab代码实现)
  3. ios系统自带推送(ios自学笔记)
  4. 申请商标变更的注意事项有哪些?
  5. android xml中attribute,android – 我无法从我的XML资源中读取AttributeSet
  6. 区块链 - 为何元宇宙上了时代周刊?
  7. js过滤器filter的使用
  8. 电路原理实验六:戴维南定理与诺顿定理的验证
  9. 信息学奥赛一本通 1252:走迷宫 | OpenJudge NOI 2.5 2753:走迷宫
  10. 用几句诗诗来勉励自己有计划的学习和进步,不忘理想珍惜时间