带有 HTTPPasswordMgrWithDefaultRealm 和 POST 数据的基本身份验证 urllib2

发布于 2024-12-29 05:06:27 字数 2330 浏览 7 评论 0原文

我有一个完美运行的 cURL 调用:

curl -H 'X-Requested-With: SO demo' -d 'parameter=value' https://username:[email protected]/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 调用(有效):

curl -H 'X-Requested-With: SO demo' -d 'parameter=value' https://username:[email protected]/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 以“.php”结尾时 urllib2 可以工作,但当 uri 以“/”结尾时不起作用

I have this cURL call that works perfectly:

curl -H 'X-Requested-With: SO demo' -d 'parameter=value' https://username:[email protected]/api/work/

My conversion does not 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

Here's what I don't get. The same server has a separate API which similar code does work on, where the only thing that has changed is the parameter and uri. Note the cURL call works on both API calls.

Second API cURL call (that works):

curl -H 'X-Requested-With: SO demo' -d 'parameter=value' https://username:[email protected]/api2/call.php

Equivalent code that works below:

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()

Why does urllib2 work when the uri ends with a '.php', but not work when the uri ends with a '/'?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

孤云独去闲 2025-01-05 05:06:27

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

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

但是如果您要像第二次运行一样执行此操作,您可能打算将其写为:

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

In the first request you are setting:

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

But if you were to do it the same as the second run, you probably meant to write it as:

uri = 'https://api.server.com/api/work/'
无法言说的痛 2025-01-05 05:06:27

来自 Python urllib2 基本身份验证问题

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

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

From Python urllib2 Basic Auth Problem

The problem [is] that the Python libraries, per HTTP-Standard, first send an unauthenticated request, and then only if it's answered with a 401 retry, are the correct credentials sent. If the ... servers don't do "totally standard authentication" then the libraries won't work.

This particular API does not respond with a 401 retry on the first attempt, it responds with an XML response containing the message that credentials were not sent.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文