urllib2 基本身份验证怪人

发布于 2024-10-15 19:13:54 字数 1623 浏览 7 评论 0原文

我正用这个把头撞在墙上。我一直在尝试每个示例,阅读我可以在网上找到的有关 urllib2 基本 http 授权的所有最后一点,但我无法弄清楚是什么导致了我的特定错误。

更令人沮丧的是,该代码适用于一个页面,但不适用于另一页面。 登录 www.mysite.com/adm 绝对顺利。验证没有问题。然而,如果我将地址更改为“http://mysite.com/adm/items.php?n=201105&c=200”,我会收到此错误:

<h4 align="center" class="teal">Add/Edit Items</h4>
<p><strong>Client:</strong> </p><p><strong>Event:</strong> </p><p class="error">Not enough information to complete this task</p>

<p class="error">This is a fatal error so I am exiting now.</p>

搜索谷歌导致此错误的信息为零。

adm 是一个框架集页面,我不确定这是否相关。

这是当前的代码:

import urllib2, urllib
import sys

import re
import base64
from urlparse import urlparse

theurl = 'http://xxxxxmedia.com/adm/items.php?n=201105&c=200'
username = 'XXXX'
password = 'XXXX'

passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
passman.add_password(None, theurl,username,password)

authhandler = urllib2.HTTPBasicAuthHandler(passman)

opener = urllib2.build_opener(authhandler)

urllib2.install_opener(opener)

pagehandle = urllib2.urlopen(theurl)

url = 'http://xxxxxxxmedia.com/adm/items.php?n=201105&c=200'
values = {'AvAudioCD': 1,
          'AvAudioCDDiscount': 00, 'AvAudioCDPrice': 50,
          'ProductName': 'python test', 'frmSubmit': 'Submit' }

#opener2 = urllib2.build_opener(urllib2.HTTPCookieProcessor())
data = urllib.urlencode(values)
req = urllib2.Request(url, data)
response = urllib2.urlopen(req)

这只是我尝试过的众多版本之一。我已经遵循了 Urllib2 Missing Manual 中的每个示例,但仍然收到相同的错误。

谁能指出我做错了什么?

I'm slamming my head against the wall with this one. I've been trying every example, reading every last bit I can find online about basic http authorization with urllib2, but I can not figure out what is causing my specific error.

Adding to the frustration is that the code works for one page, and yet not for another.
logging into www.mysite.com/adm goes absolutely smooth. It authenticates no problem. Yet if I change the address to 'http://mysite.com/adm/items.php?n=201105&c=200' I receive this error:

<h4 align="center" class="teal">Add/Edit Items</h4>
<p><strong>Client:</strong> </p><p><strong>Event:</strong> </p><p class="error">Not enough information to complete this task</p>

<p class="error">This is a fatal error so I am exiting now.</p>

Searching google has lead to zero information on this error.

The adm is a frame set page, I'm not sure if that's relevant at all.

Here is the current code:

import urllib2, urllib
import sys

import re
import base64
from urlparse import urlparse

theurl = 'http://xxxxxmedia.com/adm/items.php?n=201105&c=200'
username = 'XXXX'
password = 'XXXX'

passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
passman.add_password(None, theurl,username,password)

authhandler = urllib2.HTTPBasicAuthHandler(passman)

opener = urllib2.build_opener(authhandler)

urllib2.install_opener(opener)

pagehandle = urllib2.urlopen(theurl)

url = 'http://xxxxxxxmedia.com/adm/items.php?n=201105&c=200'
values = {'AvAudioCD': 1,
          'AvAudioCDDiscount': 00, 'AvAudioCDPrice': 50,
          'ProductName': 'python test', 'frmSubmit': 'Submit' }

#opener2 = urllib2.build_opener(urllib2.HTTPCookieProcessor())
data = urllib.urlencode(values)
req = urllib2.Request(url, data)
response = urllib2.urlopen(req)

This is just one of the many versions I've tried. I've followed every example from Urllib2 Missing Manual but still receive the same error.

Can anyone point to what I'm doing wrong?

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

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

发布评论

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

评论(4

情话已封尘 2024-10-22 19:13:54

今天遇到类似的问题。我在正在开发的网站上使用基本身份验证,但无法对任何用户进行身份验证。

您可以使用以下一些内容来调试问题:

  1. 我使用了 slumber.inhttplib2 用于测试目的。我从 ipython shell 运行这两个命令来查看收到的响应。
  2. Slumber 实际上在幕后使用了 httplib2,因此它们的行为类似。我使用 tcpdump 和后来的 tcpflow(它以更易读的形式显示信息)来查看真正发送和接收的内容。如果您需要 GUI,请参阅wireshark 或替代方案。
  3. 我使用curl测试了我的网站,当我使用curl和我的用户名/密码时,它工作正常并显示了请求的页面。但 sleep 和 httplib2 仍然无法工作。
  4. 我测试了我的网站和 browserspy.dk 看看有什么区别。重要的是 browserspy 的网站适用于基本身份验证,而我的网站则不然,所以我可以对两者进行比较。我在很多地方读到,您需要发送 HTTP 401 未授权,以便您使用的浏览器或工具可以发送您提供的用户名/密码。但我不知道的是,您还需要标头中的 WWW-Authenticate 字段。所以这就是缺失的部分。
  5. 整个情况变得奇怪的是,在测试时我会看到 httplib2 发送带有大多数请求的基本身份验证标头(tcpflow 会显示这一点)。事实证明,该库不会在第一个请求时发送用户名/密码身份验证。如果响应中包含“Status 401”和“WWW-Authenticate”,则凭据将在第二个请求以及此后发送到该域的所有请求上发送。

总而言之,您的应用程序可能是正确的,但您可能不会返回客户端发送凭据的标准标头和状态代码。使用调试工具来查找哪个是哪个。另外,httplib2 还有调试模式,只需设置 httplib2.debuglevel=1 即可将调试信息打印在标准输出上。这比使用 tcpdump 更有帮助,因为它处于更高的级别。

希望这对某人有帮助。

Run into a similar problem today. I was using basic authentication on the website I am developing and I couldn't authenticate any users.

Here are a few things you can use to debug your problem:

  1. I used slumber.in and httplib2 for testing purposes. I ran both from ipython shell to see what responses I was receiving.
  2. Slumber actually uses httplib2 beneath the covers so they acted similarly. I used tcpdump and later tcpflow (which shows information in a much more readable form) to see what was really being sent and received. If you want a GUI, see wireshark or alternatives.
  3. I tested my website with curl and when I used curl with my username/password it worked correctly and showed the requested page. But slumber and httplib2 were still not working.
  4. I tested my website and browserspy.dk to see what were the differences. Important thing is browserspy's website works for basic authentication and my web site did not, so I could compare between the two. I read in a lot of places that you need to send HTTP 401 Not Authorized so that the browser or the tool you are using could send the username/password you provided. But what I didn't know was, you also needed the WWW-Authenticate field in the header. So this was the missing piece.
  5. What made this whole situation odd was while testing I would see httplib2 send basic authentication headers with most of the requests (tcpflow would show that). It turns out that the library does not send username/password authentication on the first request. If "Status 401" AND "WWW-Authenticate" is in the response, then the credentials are sent on the second request and all the requests to this domain from then on.

So to sum up, your application may be correct but you might not be returning the standard headers and status code for the client to send credentials. Use your debug tools to find which is which. Also, there's debug mode for httplib2, just set httplib2.debuglevel=1 so that debug information is printed on the standard output. This is much more helpful then using tcpdump because it is at a higher level.

Hope this helps someone.

-残月青衣踏尘吟 2024-10-22 19:13:54

大约一年前,我经历了相同的过程并记录了我如何解决问题 - 直接而简单的身份验证方法和标准方法。选择您认为合适的。

Python 中的 HTTP 身份

验证 在 缺少 urllib2 文档

About an year ago, I went thro' the same process and documented how I solved the problem - The direct and simple way to authentication and the standard one. Choose what you deem fit.

HTTP Authentication in Python

There is an explained description, in the missing urllib2 document.

呆橘 2024-10-22 19:13:54

从您发布的 HTML 来看,它仍然认为您身份验证成功,但随后在处理您的 POST 请求时遇到错误。我尝试了你的 URL,但身份验证失败,我得到一个标准的 401 页面。

无论如何,我建议您再次尝试运行代码并在 Firefox 中手动执行相同的操作,只是这次使用 Wireshark 来捕获交换。您可以获取两种情况下 HTTP 请求和响应的全文并比较差异。在大多数情况下,这将引导您找到错误的根源。

From the HTML you posted, it still think that you authenticate successfully but encounter an error afterwards, in the processing of your POST request. I tried your URL and failing authentication, I get a standard 401 page.

In any case, I suggest you try again running your code and performing the same operation manually in Firefox, only this time with Wireshark to capture the exchange. You can grab the full text of the HTTP request and response in both cases and compare the differences. In most cases that will lead you to the source of the error you get.

柳絮泡泡 2024-10-22 19:13:54

我还发现路人的东西不起作用(有时?)。按照此答案添加base64用户/通行标头 https://stackoverflow.com/a/18592800/623159 确实有效为我。我正在访问 jenkins URL,如下所示: http:///job//lastCompletedBuild/testR‌‌ eport/api/python

这对我有用:

import urllib2
import base64

baseurl="http://jenkinsurl"
username=...
password=...

url="%s/job/jobname/lastCompletedBuild/testReport/api/python" % baseurl

base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '')
request = urllib2.Request(url)
request.add_header("Authorization", "Basic %s" % base64string) 
result = urllib2.urlopen(request)
data = result.read()

这对我不起作用,每次都会出现错误 403:

import urllib2

baseurl="http://jenkinsurl"
username=...
password=...

##urllib2.HTTPError: HTTP Error 403: Forbidden
passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
passman.add_password(None, url, username,password)
urllib2.install_opener(urllib2.build_opener(urllib2.HTTPBasicAuthHandler(passman)))
req = urllib2.Request(url)
result = urllib2.urlopen(req)
data = result.read()

I also found the passman stuff doesn't work (sometimes?). Adding the base64 user/pass header as per this answer https://stackoverflow.com/a/18592800/623159 did work for me. I am accessing jenkins URL like this: http:///job//lastCompletedBuild/testR‌​‌​eport/api/python

This works for me:

import urllib2
import base64

baseurl="http://jenkinsurl"
username=...
password=...

url="%s/job/jobname/lastCompletedBuild/testReport/api/python" % baseurl

base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '')
request = urllib2.Request(url)
request.add_header("Authorization", "Basic %s" % base64string) 
result = urllib2.urlopen(request)
data = result.read()

This doesn't work for me, error 403 each time:

import urllib2

baseurl="http://jenkinsurl"
username=...
password=...

##urllib2.HTTPError: HTTP Error 403: Forbidden
passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
passman.add_password(None, url, username,password)
urllib2.install_opener(urllib2.build_opener(urllib2.HTTPBasicAuthHandler(passman)))
req = urllib2.Request(url)
result = urllib2.urlopen(req)
data = result.read()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文