Как отправить HTTP-запрос с базовой HTTP-аутентификацией через витую структуру
Я получил <HTML><HEAD><TITLE>401 Unauthorized</TITLE></HEAD>
ошибка, когда я запускаю код с http://twistedmatrix.com/documents/13.2.0/web/howto/client.html, но я не знаю, как добавить аутентификацию в запрос.
Обновить
Я обновил свой код до этого:
from base64 import b64encode
authorization = b64encode(b"admin:admin")
d = agent.request(
'GET',
'http://172.19.1.76/',
Headers(
{
'User-Agent': ['Twisted Web Client Example'],
b"authorization": b"Basic " + authorization
}
),
None)
Но получил следующую ошибку, но я не знаю, какой контент в списке я должен предоставить.
packages/twisted/web/http_headers.py", line 199, in setRawHeaders
"instance of %r instead" % (name, type(values)))
TypeError: Header entry 'authorization' should be list but found instance of <type 'str'> instead
Обновить
Содержимое запроса должно быть в одном списке, например:
"authorization": ["Basic " + authorization]
3 ответа
Решение
Вы можете добавить заголовки к запросам, отправленным с помощью Agent
(обратите внимание на строку 29 примера, на который вы ссылались).
Например, чтобы выполнить базовую аутентификацию / авторизацию, вы можете попробовать что-то вроде этого:
from base64 import b64encode
authorization = b64encode(b"username:password")
getting = agent.request(..., Headers({b"authorization": [b"Basic " + authorization]}))
Ты можешь использовать treq
Поддержка аутентификации, вот так:
d = treq.get(
'http://...',
auth=('username', 'password')
)
В качестве полного примера:
from twisted.trial import unittest
from urllib import urlencode
from base64 import b64encode
from twisted.python.log import err
from twisted.web.client import Agent, readBody
from twisted.internet import reactor
from twisted.internet.ssl import ClientContextFactory
from twisted.web.http_headers import Headers
from zope.interface import implements
from twisted.internet.defer import succeed
from twisted.web.iweb import IBodyProducer
class StringProducer(object):
implements(IBodyProducer)
def __init__(self, body):
self.body = body
self.length = len(body)
def startProducing(self, consumer):
consumer.write(self.body)
return succeed(None)
def pauseProducing(self):
pass
def stopProducing(self):
pass
class WebClientContextFactory(ClientContextFactory):
def getContext(self, hostname, port):
return ClientContextFactory.getContext(self)
class HttpsClientTestCases(unittest.TestCase):
def test_https_client(self):
def cbRequest(response):
print 'Response version:', response.version
print 'Response code:', response.code
print 'Response phrase:', response.phrase
print 'Response headers:[{}]'.format(list(response.headers.getAllRawHeaders()))
d = readBody(response)
d.addCallback(cbBody)
return d
def cbBody(body):
print 'Response body:'
print body
contextFactory = WebClientContextFactory()
agent = Agent(reactor, contextFactory)
authorization = b64encode(b"username:password")
data = StringProducer({'hello': 'world'})
d = agent.request(
'POST',
'https://....',
headers = Headers(
{
'Content-Type': ['application/x-www-form-urlencoded'],
'Authorization': ['Basic ' + authorization]
}
),
bodyProducer = data
)
d.addCallbacks(cbRequest, err)
d.addCallback(lambda ignored: reactor.stop())
return d