有没有办法在PyQt4中强制使用QNetworkAccessManager进行身份验证?

时间:2017-09-01 15:37:32

标签: python qt pyqt pyqt4 qnetworkaccessmanager

在我的实现中,似乎QNetworkAccessManager在成功验证后缓存了用于特定网址的凭据。

使用不同的凭据对同一网址的后续请求将成功,但仅限于它使用缓存的凭据而不是新的凭据(不会发出authenticationRequired信号)。< / p>

(Py)Qt4中是否有某种方法可以清除缓存或以其他方式强制更新缓存的凭据?我应该删除经理并构建一个新经理吗?或者还有其他我做错了吗?

Qt 5提供clearAccessCache()方法,但据我所知,Qt 4没有。

这个小例子说明了问题:

import sys
import json
from PyQt4 import QtNetwork, QtGui, QtCore

def show_reply_content(reply):
    content = json.loads(str(reply.readAll()))
    if 'authenticated' in content and content['authenticated']:
        print 'authentication successful for user {}'.format(
            content['user'])
        reply.manager().replies_authenticated += 1

    # Quit when all replies are finished
    reply.deleteLater()
    reply.manager().replies_unfinished -= 1
    if not reply.manager().replies_unfinished:
        print 'number of successful authentications: {}'.format(
            reply.manager().replies_authenticated)
        app.quit()


def provide_credentials(reply, authenticator):
    print 'Setting credentials for {}:\nusername: {}\n' \
          'password: {}\n\n'.format(reply.url(),
                                    reply.credentials['username'],
                                    reply.credentials['password'])
    authenticator.setUser(reply.credentials['username'])
    authenticator.setPassword(reply.credentials['password'])

# Some initialization
app = QtGui.QApplication(sys.argv)
manager = QtNetwork.QNetworkAccessManager()
manager.finished.connect(show_reply_content)
manager.authenticationRequired.connect(provide_credentials)
manager.replies_unfinished = 0
manager.replies_authenticated = 0

# Specify credentials
all_credentials = [dict(username='aap',
                        password='njkrfnq'),
                   dict(username='noot',
                        password='asdfber')]

# url authenticates successfully only for the specified credentials
url = 'http://httpbin.org/basic-auth/{}/{}'.format(
    *all_credentials[1].values())

# Schedule requests
replies = []
for credentials in all_credentials:
    replies.append(
        manager.get(QtNetwork.QNetworkRequest(QtCore.QUrl(url))))

    # Add credentials as dynamic attribute
    replies[-1].credentials = credentials

    manager.replies_unfinished += 1

# Start event loop
app.exec_()

一旦成功验证了一个请求,下一个请求也是如此,即使它不应该是。

1 个答案:

答案 0 :(得分:1)

事实证明,有几个类似的Qt错误报告仍处于打开状态:QTBUG-16835QTBUG-30433 ...

我想应该可以使用var obj = new Object(); obj.name='t1'; obj.value='t2'; obj.hasOwnProperty('value'); // Return true if exist otherwise false ,但我无法使用不同(有效)凭据集对同一网址发出多个请求。

可能的解决方法是忘记QNetworkRequest.AuthenticationReuseAttribute信号/插槽的所有内容,并为每个请求添加原始标头(RFC 7617),正好as described here

在示例中意味着删除authenticationRequired信号/插槽连接并用以下行替换authenticationRequired部分(对于带有PyQt4的Python 2.7):

manager.get()

然而,正如@ekhumoro在上面的评论中指出的那样:不确定这是多么安全。