使用HTTPPasswordMgrWithDefaultRealm和POST数据的基本Auth urllib2

时间:2012-01-27 22:38:58

标签: python urllib2 basic-authentication unauthorized http-error

我有这个完美的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()

当uri以“。”结尾时,为什么urllib2工作,但当uri以'/'结尾时,无法工作

2 个答案:

答案 0 :(得分:2)

在您要设置的第一个请求中:

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

但是如果你要像第二次运行那样做,你可能想把它写成:

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

答案 1 :(得分:1)

来自Python urllib2 Basic Auth Problem

  

问题是,根据HTTP-Standard,Python库首先发送未经身份验证的请求,然后只有在回复401重试时,才会发送正确的凭据。如果...服务器不进行“完全标准认证”,则库将无法工作。

此特定API在第一次尝试时不响应401重试,它以包含未发送凭据的消息的XML响应进行响应。