Python 使用HTTPPasswordMgrWithDefaultRealm和POST数据对urllib2进行基本身份验证

Python 使用HTTPPasswordMgrWithDefaultRealm和POST数据对urllib2进行基本身份验证,python,urllib2,basic-authentication,unauthorized,http-error,Python,Urllib2,Basic Authentication,Unauthorized,Http Error,我有一个很好用的卷发电话: 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 usernam

我有一个很好用的卷发电话:

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,类似的代码可以使用该API,其中唯一更改的是参数和uri。请注意,cURL调用对两个API调用都有效

第二个API cURL调用(有效):

等效代码如下所示:

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以“/”结尾时不工作?

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

uri = 'https://api.domain.com/api/work/'
但是,如果您与第二次运行时的操作相同,您可能打算将其编写为:

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

在第一个请求中,您正在设置:

uri = 'https://api.domain.com/api/work/'
但是,如果您与第二次运行时的操作相同,您可能打算将其编写为:

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

问题是,根据HTTP标准,Python库首先发送未经验证的请求,然后只有在401重试的情况下才发送正确的凭据。如果。。。如果服务器不执行“完全标准的身份验证”,那么库将无法工作

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

From

问题是,根据HTTP标准,Python库首先发送未经验证的请求,然后只有在401重试的情况下才发送正确的凭据。如果。。。如果服务器不执行“完全标准的身份验证”,那么库将无法工作


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

第二次Python运行是对同一uri的第二次curl运行的比较。我想我很困惑,为什么有时调用api.domain.com,有时调用api.server.com。服务器有两个不同内容的api版本对于每个版本。第二次Python运行是对同一uri的第二次curl运行的比较。我想我不明白为什么有时您调用api.domain.com,有时调用api.server.com。服务器有两个api版本,每个版本的内容不同。发布复制和粘贴样板文件/逐字记录时要小心对于多个问题的答案,这些问题往往被社区标记为“垃圾邮件”。如果你这样做的话,通常意味着问题是重复的,所以把它们标记为:谢谢,凯文。结果证明解决方案是相同的,但我只是看到问题的不同症状。还是应该是dup吗?在发布多个问题的复制粘贴样板/逐字回答时要小心,这些问题往往被社区标记为“垃圾邮件”。如果你这样做的话,通常意味着问题是重复的,所以把它们标记为:谢谢,凯文。结果证明解决方案是相同的,但我只是看到问题的不同症状。还应该是个傻瓜吗?