• Qt写一个惠尔顿网络自动登录程序


    QT做一个惠尔顿自动登录程序。

    出于某种要求,公司使用了这个惠尔顿网络安全审计系统。

    关键是这个做得不太行吧,提供的GUI程序,又大又难用(搞不懂,简单的东西做这么复杂)。

    还提供了网页登录程序,这个就简单,只需要输入账号密码点击登录即可。

    但是吧,他喵的,必须保持登录页面打开,也就是一直占用那个浏览器的一个标签页。

    这他喵的也很恶心了,尤其是针对浏览器使用和切换都很频繁的人来说。

    是可忍,孰不可忍。使用fidlder一抓包,一Compaser post一下,就发现了登录的网页,以及参数。

    POST http://192.168.0.98/user-login-auth HTTP/1.1
    Host: 192.168.0.98
    Content-Type: application/x-www-form-urlencoded; charset=UTF-8
    
    param%5BUserName%5D=username&param%5BUserPswd%5D=123456
    
    
    

    网页版确实简单,可以精简到简单的post账号和密码就能验证通过,当然,需要对一些字符进行url编码

    没什么好分析的,谈需求。

    1.越简单越好,我们只想使用这软件一次,以后再也不用自己输出账号密码,然后点击登录。
    那就需要读写文件,保存账号密码。//简单起见,自己构造个json文件即可
    那就需要开机自动运行。//注册表操作
    2.虽然我没遇见过,但是他们反映使用过程中,虽然登录成功,但是后面还是断网了。也就是连接可能不稳定。
    那就需要不停的检测网络连接,断网就需要自己post登录。
    3.虽然直接打包成压缩文件也能用,但是使用的对象不全是程序员,要是随便的移动软件,岂不是多了很多注册表垃圾。
    那就弄成安装包吧。
    

    主体代码如下:

    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include <QWidget>
    #include <QDebug>
    #include <QNetworkRequest>
    #include <QMessageBox>
    #include <QNetworkReply>
    #include <QNetworkAccessManager>
    #include <QFile>
    #include <iostream>
    #include <QCloseEvent>
    #include <QTimer>
    //#define DEBUG
    #define QS(x) QString::fromUtf8(x)
    QT_BEGIN_NAMESPACE
    namespace Ui { class Widget; }
    QT_END_NAMESPACE
    
    class Widget : public QWidget
    {
        Q_OBJECT
    
    public:
        Widget(QWidget *parent = nullptr);
        ~Widget();
        bool checkFile();
        void autoLogin(QString un,QString ps);
        void CreateSystemTrayIcon();
    private slots:
        void on_pushButton_clicked();
        void requestFinished(QNetworkReply*);
    
        void on_lineEdit_2_returnPressed();
    
    private:
        Ui::Widget *ui;
        QString success;
        QString fail;
        QString username = "";
        QString password = "";
        QTimer time;
    #ifdef DEBUG
        const QString LOGIN = "http://192.168.0.102:90/test.html";
    #else
        const QString LOGIN="http://192.168.0.98/user-login-auth";
    #endif
    protected:
        void closeEvent(QCloseEvent *event);//由于要关闭窗口变为隐藏至托盘图标,所以要重写close事件
    
    };
    #endif // WIDGET_H
    
    
    #include "widget.h"
    #include "ui_widget.h"
    #include "jsonxx.h"
    #include "jsonxx.cc"
    #include <qnetworkproxy.h>
    #include <QTextCodec>
    #include <QMenu>
    #include <QSystemTrayIcon>
    #include <QAction>
    #include <QSettings>
    using namespace std;
    using namespace jsonxx;
    #define AUTO_RUN_KEY	"HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"
    //#define DEBUG
    Widget::Widget(QWidget *parent)
        : QWidget(parent)
        , ui(new Ui::Widget)
    {
        ui->setupUi(this);
    
        success = "color:green";
        fail = "color:red";
        time.setInterval(30000);//30s自动登录一次
        QObject::connect(&time, &QTimer::timeout, [=]()
        {
            autoLogin(username,password);
        });
        if(checkFile())
        {
            //隐藏到托盘
            CreateSystemTrayIcon();
        }
    }
    
    Widget::~Widget()
    {
        delete ui;
    }
    
    //读取配置文件
    bool Widget::checkFile()
    {
    
        QFile file("config.txt");
        if(!file.open(QIODevice::ReadOnly|QIODevice::Text))
        {
            qDebug()<<file.errorString();
            return false;
        }
        else
        {
            qDebug()<<"openok";
        }
        QByteArray tt = file.read(1024);
        QString tta;
        tta = tta.fromLocal8Bit(tt);
        string str = tta.toStdString();
        Object o;
        if(o.parse(str))
        {
            QString username = "";
            QString password = "";
            QString tmp = "";
            qDebug()<<"success to parse";
            if(!o.has<String>("un"))
            {
                return false;
            }
            str = o.get<String>("un");
            username = QString::fromStdString(str);
            ui->lineEdit->setText(username);
            if(!o.has<String>("ps"))
            {
                return false;
            }
            str = o.get<String>("ps");
            password = QString::fromStdString(str);
            ui->lineEdit_2->setText(password);
            if(!o.has<String>("autoLogin"))
            {
                qDebug()<<"meiyou";
                return false;
            }
            str = o.get<String>("autoLogin");
            tmp = QString::fromStdString(str);
            if("true"!=tmp){
                return false;
            }
            ui->checkBox->setCheckState(Qt::Checked);
            autoLogin(username,password);
        }else{
            return false;
        }
    }
    
    void Widget::autoLogin(QString un, QString ps)
    {
        QNetworkRequest request;
        QNetworkAccessManager* naManager = new QNetworkAccessManager(this);
        QMetaObject::Connection connRet = QObject::connect(naManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(requestFinished(QNetworkReply*)));
        Q_ASSERT(connRet);
        request.setUrl(QUrl(LOGIN));
        request.setHeader(QNetworkRequest::ContentTypeHeader,"application/x-www-form-urlencoded");
        QByteArray postData;
    #ifdef DEBUG
        QNetworkProxy proxy;
        proxy.setHostName("127.0.0.1");
        proxy.setPort(8888);
        naManager->setProxy(proxy);
    #endif
        QString s = QUrl::toPercentEncoding("param[UserName]") + "=" + QUrl::toPercentEncoding(un) + "&" + QUrl::toPercentEncoding("param[UserPswd]") + "=" + QUrl::toPercentEncoding(ps);
        postData.append(s);
        qDebug()<<s<<endl;
        naManager->post(request,postData);
        username = un;
        password = ps;
    }
    
    void Widget::CreateSystemTrayIcon()
    {
        QAction* show = new QAction(QS("打开界面"));
        QAction* login = new QAction(QS("登录"));
        QAction* quit = new QAction(QS("退出"));
    
        connect(show, &QAction::triggered, this, [=]()
        {
            this->showNormal();
        });
        connect(login, &QAction::triggered, this, [=]()
        {
            if(!username.isEmpty()&&!password.isEmpty())
            {
                this->autoLogin(username,password);
            }
            else
            {
                on_pushButton_clicked();
            }
        });
        connect(quit , &QAction::triggered, this, [=]()
        {
            qDebug()<<"exit";
            QApplication::exit(0);
        });
    
        QMenu* trayMenu = new QMenu(this);//菜单
        trayMenu->addAction(show);
        trayMenu->addAction(login);
        trayMenu->addAction(quit);
    
        //创建一个系统托盘
        QSystemTrayIcon* trayIcon = new QSystemTrayIcon(this);
        trayIcon->setIcon(QIcon(QPixmap(":/photo/pic.ico")));
        trayIcon->setContextMenu(trayMenu);//设置菜单
        trayIcon->show();
        connect(trayIcon, &QSystemTrayIcon::activated, this, [=](QSystemTrayIcon::ActivationReason reason)
        {
            qDebug()<<reason;
            qDebug()<<QApplication::mouseButtons();
            if(reason == QSystemTrayIcon::Trigger&&QApplication::mouseButtons()==Qt::LeftButton)
            {
                this->showNormal();
            }
            else
            {
                qDebug()<<"没到条件";
            }
        });
    
    }
    
    void Widget::requestFinished(QNetworkReply * reply)
    {
        QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
        if(statusCode.isValid())
        {
            qDebug() << "status code=" << statusCode.toInt();
        }
    
        QVariant reason = reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
        if(reason.isValid())
        {
            qDebug() << "reason=" << reason.toString();
    #ifdef DEBUG
            if(reason.toString().contains("allowed",Qt::CaseInsensitive))
            {
                qDebug()<<"success";
                ui->label_3->setStyleSheet(success);
                ui->label_3->setText(QS("登录成功"));
                time.start();
            }
            else
            {
                qDebug()<<"fail";
                ui->label_3->setStyleSheet(fail);
                ui->label_3->setText(QS("登录失败"));
                time.stop();
                username = "";
                password = "";
                this->showNormal();
            }
    #endif
        }
    
        QNetworkReply::NetworkError err = reply->error();
        if(err != QNetworkReply::NoError) {
            qDebug() << "Failed: " << reply->errorString();//弹出警告框
            ui->label_3->setStyleSheet(fail);
            ui->label_3->setText(QS("登录失败"));
            username = "";
            password = "";
            time.stop();
            this->showNormal();
            return;
        }
        else {
            QString s = reply->readAll();
            if(s.contains("success",Qt::CaseInsensitive))//不区分大小写
            {
                ui->label_3->setStyleSheet(success);
                ui->label_3->setText(QS("登录成功"));
                time.start();
            }
            else
            {
                ui->label_3->setStyleSheet(fail);
                ui->label_3->setText(QS("登录失败"));
                username = "";
                password = "";
                time.stop();
                this->showNormal();
            }
        }
    }
    
    
    void Widget::on_pushButton_clicked()
    {
        bool check = ui->checkBox->checkState();
        QString username = ui->lineEdit->text();
        QString password = ui->lineEdit_2->text();
        if(username.isEmpty())
        {
            QMessageBox::information(NULL,QS("提示"),QS("请输入账号"),QMessageBox::Ok);
            return;
        }
        if(password.isEmpty())
        {
            QMessageBox::information(NULL,QS("提示"),QS("请输入账号"),QMessageBox::Ok);
            return;
        }
        qDebug()<<username<<endl;
        qDebug()<<password<<endl;
        if(check)
        {
            QString str = "";
            str = "{'un':'"+username+"','ps':'"+password+"','autoLogin':'true'}";
            QFile file("config.txt");
            if(!file.open(QIODevice::WriteOnly | QIODevice::Text))
            {
                return;
            }
            QByteArray data = str.toLocal8Bit();
            file.write(data);
            qDebug()<<"length = "<<data.length()<<endl;
            file.close();
            QString application_name = QApplication::applicationName();//获取应用名称
            QSettings *settings = new QSettings(AUTO_RUN_KEY, QSettings::NativeFormat);//创建QSetting, 需要添加QSetting头文件
            QString application_path = QApplication::applicationFilePath();//找到应用的目录
            settings->setValue(application_name, application_path.replace("/", "\\"));//写入注册表
        }
        else
        {
            QString str = "";
            str = "{'un':'"+username+"','ps':'"+password+"','autoLogin':'true'}";
            QFile file("config.txt");
            if(!file.open(QIODevice::WriteOnly | QIODevice::Text))
            {
                return;
            }
            QByteArray data = str.toLocal8Bit();
            file.write(data);
            qDebug()<<"length = "<<data.length()<<endl;
            file.close();
        }
        autoLogin(username,password);
    }
    
    void Widget::on_lineEdit_2_returnPressed()
    {
        on_pushButton_clicked();
    }
    
    void Widget::closeEvent(QCloseEvent *event)
    {
        hide();//隐藏窗口
        event->ignore();//忽略关闭事件
    }
    
    

    C++开发的json解析

    json解析来自于github,虽然qt也有json解析,但是哪有我直接从以前工程复制代码来得爽快。

    也许还有完善的地方吧,反正先用用再说了。

    image

    简直是离谱,家里写的源代码加上innosetup的压缩包,竟然也能检测出病毒来。

    image

    真是呵呵了。
    image

    测试一下,登录成功了。也能上网了,那就是能用。
    源代码下载

  • 相关阅读:
    【51nod】2590 持续讨伐
    【51nod】2589 快速讨伐
    【51nod】2606 Secondary Substring
    【LOJ】#3098. 「SNOI2019」纸牌
    【洛谷】P4202 [NOI2008]奥运物流
    【LOJ】#3103. 「JSOI2019」节日庆典
    【LOJ】#3102. 「JSOI2019」神经网络
    【洛谷】P5348 密码解锁
    【洛谷】P4883 mzf的考验
    【LOJ】#3101. 「JSOI2019」精准预测
  • 原文地址:https://www.cnblogs.com/dayq/p/16176960.html
Copyright © 2020-2023  润新知