【问题标题】:Get sslerrors signal in QWebEngineView在 QWebEngineView 中获取 sslerrors 信号
【发布时间】:2019-03-22 21:21:54
【问题描述】:

我正在开发一个用户必须先登录的应用程序。我正在使用 QWebEngineView 来显示登录页面。但是在其中一台机器中,该页面没有显示。我想知道是否有任何 SSL 错误。如何获取 sslerrors 信号并将其连接到插槽。下面的示例代码

from PyQt5.QtNetwork import QSslConfiguration, QSsl
from PyQt5.QtWidgets import QWidget, QGridLayout, QStatusBar, QApplication,\
    QMainWindow
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage
from PyQt5.QtCore import QCoreApplication, QMetaObject, QUrl

def set_ssl_protocol():
    default_config = QSslConfiguration.defaultConfiguration()
    default_config.setProtocol(QSsl.TlsV1_2)
    QSslConfiguration.setDefaultConfiguration(default_config)

set_ssl_protocol()

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):

        self.urlString = "https://www.yahoo.com"

        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")
        self.webView = QWebEngineView(self.centralwidget)
        self.webView=QWebEngineView()
        self.webView.setUrl(QUrl("about:blank"))
#        self.webView.setUrl(QUrl("http://www.google.com/"))
        self.webView.setObjectName("webView")
        self.gridLayout.addWidget(self.webView, 0, 0, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.loadURL()
        self.retranslateUi(MainWindow)
        QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))

    def loadURL(self):
        if not hasattr(self, 'page'):
            self.page = QWebEnginePage()
            self.webView.setPage(self.page)
        self.page.load(QUrl(self.urlString))


if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    MainWindow = QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

注意:在 Qt4 中这很容易,因为我们可以将 page().networkAccessManager().sslerrors 信号连接到插槽,而在 Qt5 中,由于请求不是通过 NetworkAccessManager 发出的,因此调试起来有点困难。

【问题讨论】:

    标签: python pyqt pyqt5 qtnetwork qwebengineview


    【解决方案1】:

    如果你想通过覆盖QWebEnginePagecertificateError()方法来获取SSL证书导致的错误信息,如下所示:

    from PyQt5 import QtCore, QtWidgets, QtNetwork, QtWebEngineWidgets
    
    
    def set_ssl_protocol():
        default_config = QtNetwork.QSslConfiguration.defaultConfiguration()
        default_config.setProtocol(QtNetwork.QSsl.TlsV1_2)
        QtNetwork.QSslConfiguration.setDefaultConfiguration(default_config)
    
    
    class WebEnginePage(QtWebEngineWidgets.QWebEnginePage):
        def certificateError(self, certificateError):
            print(certificateError.errorDescription(), certificateError.url(), certificateError.isOverridable())
            error = certificateError.error()
            if error == QtWebEngineWidgets.WebEngineCertificateError.SslPinnedKeyNotInCertificateChain:
                print("SslPinnedKeyNotInCertificateChain")
            elif error == QtWebEngineWidgets.WebEngineCertificateError.CertificateCommonNameInvalid:
                print("CertificateCommonNameInvalid")
            elif error == QtWebEngineWidgets.WebEngineCertificateError.CertificateDateInvalid:
                print("CertificateDateInvalid")
            elif error == QtWebEngineWidgets.WebEngineCertificateError.CertificateAuthorityInvalid:
                print("CertificateAuthorityInvalid")
            elif error == QtWebEngineWidgets.WebEngineCertificateError.CertificateContainsErrors:
                print("CertificateContainsErrors")
            if error == QtWebEngineWidgets.WebEngineCertificateError.CertificateNoRevocationMechanism:
                print("CertificateNoRevocationMechanism")
            elif error == QtWebEngineWidgets.WebEngineCertificateError.CertificateUnableToCheckRevocation:
                print("CertificateUnableToCheckRevocation")
            elif error == QtWebEngineWidgets.WebEngineCertificateError.CertificateRevoked:
                print("CertificateRevoked")
            elif error == QtWebEngineWidgets.WebEngineCertificateError.CertificateInvalid:
                print("CertificateAuthorityInvalid")
            elif error == QtWebEngineWidgets.WebEngineCertificateError.CertificateWeakSignatureAlgorithm:
                print("CertificateWeakSignatureAlgorithm")
            elif error == QtWebEngineWidgets.WebEngineCertificateError.CertificateNonUniqueName:
                print("CertificateNonUniqueName")
            elif error == QtWebEngineWidgets.WebEngineCertificateError.CertificateWeakKey:
                print("CertificateWeakKey")
            elif error == QtWebEngineWidgets.WebEngineCertificateError.CertificateNameConstraintViolation:
                print("CertificateNameConstraintViolation")
            elif error == QtWebEngineWidgets.WebEngineCertificateError.CertificateValidityTooLong:
                print("CertificateValidityTooLong")
            elif error == QtWebEngineWidgets.WebEngineCertificateError.CertificateTransparencyRequired:
                print("CertificateTransparencyRequired")
    
            return super(WebEnginePage, self).certificateError(certificateError)
    
    
    class MainWindow(QtWidgets.QMainWindow):
        def __init__(self, parent=None):
            super(MainWindow, self).__init__(parent)
            self.webView = QtWebEngineWidgets.QWebEngineView()
            self.setCentralWidget(self.webView)
            page = WebEnginePage(self)
            self.webView.setPage(page)
            page.load(QtCore.QUrl("https://www.yahoo.com"))
    
    
    if __name__ == "__main__":
        import sys
        app = QtWidgets.QApplication(sys.argv)
        set_ssl_protocol()
        w = MainWindow()
        w.show()
        sys.exit(app.exec_())
    

    如果你想包含或不包含请求,你可以分别返回 True 或 False。

    【讨论】:

    • 感谢您的回复。由于页面是空白的,我不知道可能是什么错误。它只能归因于证书错误吗?如果还有其他一些 SSL 错误,我该如何知道?我只是想知道原因并调试此问题。
    • @TFA 您的问题是如何通知是否存在 SSL 类型错误,并且我指出的方法符合您的要求,这涵盖了 Qt 支持的所有错误。另一方面,如果错误不是由 SSL 我无法帮助你,因为你没有提供minimal reproducible example。最后,如果我的回答对你有帮助,别忘了标记为正确,如果你不知道怎么做,请查看tour,这是最好的感谢方式
    • @eyllansec 虽然这个最小的例子足以理解这个问题,但这里的问题是,除了一台特定的机器之外,它无法在所有机器上重现,这让我现在认为它很可能是环境特定问题。赞成您的回答。
    • @TFA 好吧,如果它不能被复制,那将很难提供帮助,所以由你来发现它与其他机器有什么不同。所有机器都具有相同的架构吗?他们有相同的操作系统吗?它们是同一个版本吗?
    猜你喜欢
    • 2017-03-03
    • 1970-01-01
    • 2022-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-03
    相关资源
    最近更新 更多