Базовая аутентификация urllib2 с данными HTTPPasswordMgrWithDefaultRealm и POST - PullRequest
0 голосов
/ 28 января 2012

У меня есть вызов cURL, который отлично работает:

curl -H 'X-Requested-With: SO demo' -d 'parameter=value' https://username:password@api.domain.com/api/work/

Мое преобразование не работает.

import urllib2
# Create a password manager.
password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
# Add the username and password.
top_level_url = 'https://api.server.com'
password_mgr.add_password(None, top_level_url, 'username', 'password')
handler = urllib2.HTTPBasicAuthHandler(password_mgr)
# Create "opener" (OpenerDirector instance).
opener = urllib2.build_opener(handler)
# Install the opener so all calls to urllib2.urlopen use our opener.
urllib2.install_opener(opener)
# Create request.
headers = {'X-Requested-With':'SO demo.'}
uri = 'https://api.domain.com/api/work/'
data='parameter=value'
req = urllib2.Request(uri,data,headers)
# Make request to fetch url.
result = urllib2.urlopen(req)
urllib2.HTTPError: HTTP Error 401: Unauthorized

Вот что я не понимаю. У того же сервера есть отдельный API, с которым работает похожий код, где единственное, что изменилось - это параметр и uri. Обратите внимание, что вызов cURL работает с обоими вызовами API.

Второй вызов API cURL (работает):

curl -H 'X-Requested-With: SO demo' -d 'parameter=value' https://username:password@api.domain.com/api2/call.php

Эквивалентный код, который работает ниже:

import urllib2
# Create a password manager.
password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
# Add the username and password.
top_level_url = 'https://api.server.com'
password_mgr.add_password(None, top_level_url, 'username', 'password')
handler = urllib2.HTTPBasicAuthHandler(password_mgr)
# Create "opener" (OpenerDirector instance).
opener = urllib2.build_opener(handler)
# Install the opener.
# Now all calls to urllib2.urlopen use our opener.
urllib2.install_opener(opener)
# Create request.
headers = {'X-Requested-With':'SO demo.'}
uri = 'https://api.server.com/api2/call.php'
data='parameter=value'
req = urllib2.Request(uri,data,headers)
# Make request to fetch url.
result = urllib2.urlopen(req)
# Read results.
result.read()

Почему urllib2 работает, когда uri оканчивается на «.php», но не работает , когда uri оканчивается на «/»?

Ответы [ 2 ]

2 голосов
/ 28 января 2012

В первом запросе вы устанавливаете:

uri = 'https://api.domain.com/api/work/'

Но если бы вы делали это так же, как и во втором запуске, вы, вероятно, хотели бы написать это как:

uri = 'https://api.server.com/api/work/'
1 голос
/ 03 марта 2012

С Python urllib2 Основная проблема с аутентификацией

Проблема [заключается в том, что библиотеки Python в соответствии со стандартом HTTP сначала отправляют запрос без проверки подлинности, а затем только еслиответил 401 повтор, правильные отправленные учетные данные.Если ... серверы не выполняют "полностью стандартную аутентификацию", библиотеки не будут работать.

Этот конкретный API не отвечает с 401 повтором при первой попытке, он отвечаетXML-ответ, содержащий сообщение о том, что учетные данные не были отправлены.

...