本文介绍了Qt5-QML:在第三方设备上使用的自动身份验证用户名和密码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

了解了如何将JavaScript功能集成到Qt-QML中之后,我现在尝试应用在到我实验室中的一个小现实示例.

After understanding how to integrate JavaScript functions into Qt-QML I am now trying to apply what I have learned in my previous post to a small real world example in my lab.

我正在尝试使用实验室中存在的第三方设备通过wi-fi访问机器人.

I am trying to access to my robots via wi-fi using using a third party device present in my lab.

我有设备提供的登录表格,如下图所示.该地址例如是https://123.456.789.123:7878(我编写了该地址,但这是为了理解这个主意):

I have a log-in form provided by the device as shown in the print screen given below. The address is, for example, https://123.456.789.123:7878 (which I made up but it is for understanding the idea):

使用inspector tool导航html页面后,我到达了log in按钮类,如下所示:

After navigating the html page using the inspector tool I arrived to the log in button class as shown below:

问题,我遇到的问题是我现在试图自动填充log-in的密码并自动访问它.登录后,我应该可以看到下面的页面,但是没有.

The problem I have is that I am now trying to autofill the password of the log-in and automatically access it. After logging in I should be able to see the page below, but I don't.

我应该提到我重用了快速Nanao浏览器示例因为在需要绕过需要认证的窗口时效果很好.

I should mention that I reused the Quick Nanao Browser Example beacause it does work well when there is need to by-pass a windows that requires certification.

示例

我在快速Nanao浏览器示例"上做了很多工作,以使其更简短,并准确地指出了问题出在哪里以及我如何解决该问题.

I worked a lot on the Quick Nanao Browser Example to make it much more short and focusing exactly where the problem is and how I am trying to solve it.

我正在使用的代码段如下:

The code snippet I am using is the one below:

main.cpp

#include <QtQml/QQmlApplicationEngine>
#include <QtQml/QQmlContext>
#include <QtWebEngine/qtwebengineglobal.h>
static QUrl startupUrl()
{
    QUrl ret;
    QStringList args(qApp->arguments());
    args.takeFirst();
    for (const QString &arg : qAsConst(args)) {
        if (arg.startsWith(QLatin1Char('-')))
             continue;
        ret = Utils::fromUserInput(arg);
        if (ret.isValid())
            return ret;
    }
    return QUrl(QStringLiteral("https://123.456.789.123:7878"));
}

int main(int argc, char **argv)
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QtWebEngine::initialize();
    Application app(argc, argv);
    QQmlApplicationEngine appEngine;
    Utils utils;
    appEngine.rootContext()->setContextProperty("utils", &utils);
    appEngine.load(QUrl("qrc:/ApplicationRoot.qml"));
    if (!appEngine.rootObjects().isEmpty())
        QMetaObject::invokeMethod(appEngine.rootObjects().first(), "load", Q_ARG(QVariant, startupUrl()));
    else
        qFatal("Failed to load sources");
    return app.exec();
}

ApplicationRoot.qml

import QtQuick 2.1
import QtWebEngine 1.9
QtObject {
    id: root
    property string script_password: "
        setTimeout(function(){
            var input_password = document.getElementsByName('password')[0];
            input_password.value = '%1';
            var button = document.getElementById('passwordNext');
            button.click();
            }, 100);
            ".arg(password)

    property QtObject defaultProfile: WebEngineProfile {}
    property QtObject otrProfile: WebEngineProfile {
        offTheRecord: true
    }
    property Component browserWindowComponent: BrowserWindow {
        applicationRoot: root
        onClosing: destroy()
    }    
    function createWindow(profile) {...}
    function createDialog(profile) {...}
    function load(url) {...}
}

BrowserWindow.qml

import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.0
import QtQuick.Window 2.1
import QtWebEngine 1.9

ApplicationWindow {
    id: browserWindow

    property string password: "abcdefghilmno"

    property QtObject applicationRoot
    property Item currentWebView: tabs.currentIndex < tabs.count ? tabs.getTab(tabs.currentIndex).item : null
    property int previousVisibility: Window.Windowed
    width: 1300
    height: 900
    visible: true
    title: currentWebView && currentWebView.title
    Component.onCompleted: flags = flags | Qt.WindowFullscreenButtonHint
    toolBar: ToolBar {...}
    // Necessary to accept server's certificate
    TabView {...}
    // Showing Manager Window
    WebEngineView {
        id: devToolsView
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.bottom: parent.bottom
        onNewViewRequested: function(request) {
            var tab = tabs.createEmptyTab(currentWebView.profile);
            tabs.currentIndex = tabs.count - 1;
            request.openIn(tab.item);
        }
    }
    // By-Passing the Server's Certificate using sslDialog
    MessageDialog {...}
    DownloadView {
        id: downloadView
        visible: false
        anchors.fill: parent
    }
    function onDownloadRequested(download) {
        downloadView.visible = true;
        downloadView.append(download);
        download.accept();
    }
}

非常感谢您提供有关如何解决此问题以及如何继续前进的指导.

Thank you very much for providing some guidance on how to solve this problem and how to move on.

推荐答案

下一次,有必要显示您尝试过的内容,因为它说它不起作用并且使用我之前的代码是不够的,每次登录都取决于每个系统,所以没有通用的解决方案.

For a next occasion it is necessary to show what you have tried since saying that it does not work and using my previous code is not enough, each login depends on each system so there is no generic solution.

从显示的HTML内容中,您可以得出以下结论:

From the little HTML you have shown you can deduce that:

  • 用户名输入的ID为用户名".
  • 密码输入的ID为"password".
  • 按下按钮时,将调用进行验证的函数"LSubmit()".

从我对路由器进行的实验来看,创建DOM总是会有所延迟,此外,如果输入的URL不存在,则会在其末尾添加"/".

From my experiment with my router there is always a delay in the creation of the DOM, in addition to the url that entered a "/" is added at the end if it does not exist

考虑到上述情况,解决方案是:

Considering the above, the solution is:

import QtQuick 2.13
import QtQuick.Controls 2.13
import QtWebEngine 1.9

ApplicationWindow{
    id: root
    width: 640
    height: 480
    visible: true

    property string username: "USERNAME"
    property string password: "PASSWORD"

    QtObject{
        id: internals
        property string login_script: "
            console.log('start');
            var input_username = document.getElementById('username');
            console.log('username');
            console.log(input_username);
            input_username.value = '%1';
            var input_password = document.getElementById('password');
            console.log('password');
            console.log(input_password);
            input_password.value = '%2';
            console.log('clicked');
            LSubmit();
            console.log('end');
        ".arg(username).arg(password);
    }

    Timer {
        id: timer
        interval: 1000; repeat: false
        onTriggered: view.runJavaScript(internals.login_script)
    }

    WebEngineView {
        id: view
        anchors.fill: parent
        onUrlChanged: {
            console.log(url)
            if(url == Qt.resolvedUrl("https://123.456.789.123:7878/")){
                timer.running = true   
            }
        }
        onCertificateError: function(error) {
            error.ignoreCertificateError();
        }
        Component.onCompleted: view.url = "https://123.456.789.123:7878"
    }
}

这篇关于Qt5-QML:在第三方设备上使用的自动身份验证用户名和密码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-19 15:53