Dar*_*zer 83 python authentication http
我正在玩,尝试编写一些代码来使用tr.im API来缩短URL.
在阅读http://docs.python.org/library/urllib2.html后,我尝试了:
TRIM_API_URL = 'http://api.tr.im/api'
auth_handler = urllib2.HTTPBasicAuthHandler()
auth_handler.add_password(realm='tr.im',
uri=TRIM_API_URL,
user=USERNAME,
passwd=PASSWORD)
opener = urllib2.build_opener(auth_handler)
urllib2.install_opener(opener)
response = urllib2.urlopen('%s/trim_simple?url=%s'
% (TRIM_API_URL, url_to_trim))
url = response.read().strip()
Run Code Online (Sandbox Code Playgroud)
response.code是200(我认为它应该是202).url有效,但基本的HTTP身份验证似乎没有用,因为缩短的URL不在我的URL列表中(在http://tr.im/?page=1).
在阅读http://www.voidspace.org.uk/python/articles/authentication.shtml#doing-it-properly后, 我也尝试过:
TRIM_API_URL = 'api.tr.im/api'
password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
password_mgr.add_password(None, TRIM_API_URL, USERNAME, PASSWORD)
auth_handler = urllib2.HTTPBasicAuthHandler(password_mgr)
opener = urllib2.build_opener(auth_handler)
urllib2.install_opener(opener)
response = urllib2.urlopen('http://%s/trim_simple?url=%s'
% (TRIM_API_URL, url_to_trim))
url = response.read().strip()
Run Code Online (Sandbox Code Playgroud)
但我得到了相同的结果.(response.code为200且url有效,但未在我的帐户http://tr.im/中记录.)
如果我使用查询字符串参数而不是基本HTTP身份验证,如下所示:
TRIM_API_URL = 'http://api.tr.im/api'
response = urllib2.urlopen('%s/trim_simple?url=%s&username=%s&password=%s'
% (TRIM_API_URL,
url_to_trim,
USERNAME,
PASSWORD))
url = response.read().strip()
Run Code Online (Sandbox Code Playgroud)
...然后不仅url有效,而且它记录在我的tr.im帐户中.(虽然response.code仍然是200.)
虽然我的代码一定有问题(而不是tr.im的API),因为
$ curl -u yacitus:xxxx http://api.tr.im/api/trim_url.json?url=http://www.google.co.uk
Run Code Online (Sandbox Code Playgroud)
...的回报:
{"trimpath":"hfhb","reference":"nH45bftZDWOX0QpVojeDbOvPDnaRaJ","trimmed":"11\/03\/2009","destination":"http:\/\/www.google.co.uk\/","trim_path":"hfhb","domain":"google.co.uk","url":"http:\/\/tr.im\/hfhb","visits":0,"status":{"result":"OK","code":"200","message":"tr.im URL Added."},"date_time":"2009-03-11T10:15:35-04:00"}
Run Code Online (Sandbox Code Playgroud)
...并且URL确实出现在http://tr.im/?page=1上的网址列表中.
如果我跑:
$ curl -u yacitus:xxxx http://api.tr.im/api/trim_url.json?url=http://www.google.co.uk
Run Code Online (Sandbox Code Playgroud)
...再次,我得到:
{"trimpath":"hfhb","reference":"nH45bftZDWOX0QpVojeDbOvPDnaRaJ","trimmed":"11\/03\/2009","destination":"http:\/\/www.google.co.uk\/","trim_path":"hfhb","domain":"google.co.uk","url":"http:\/\/tr.im\/hfhb","visits":0,"status":{"result":"OK","code":"201","message":"tr.im URL Already Created [yacitus]."},"date_time":"2009-03-11T10:15:35-04:00"}
Run Code Online (Sandbox Code Playgroud)
注意代码是201,消息是"tr.im URL已经创建[yacitus]".
我不能正确地进行基本的HTTP身份验证(在任一种尝试中).你能发现我的问题吗?也许我应该看一下,通过电线发送什么?我以前从未这样做过.我可以使用Python API(可能在pdb中)吗?或者我可以使用另一种工具(最好是Mac OS X)吗?
Ben*_*ing 243
这似乎工作得很好(取自另一个线程)
import urllib2, base64
request = urllib2.Request("http://api.foursquare.com/v1/user")
base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '')
request.add_header("Authorization", "Basic %s" % base64string)
result = urllib2.urlopen(request)
Run Code Online (Sandbox Code Playgroud)
Ali*_*har 20
真便宜的解决方案:
urllib.urlopen('http://user:xxxx@api.tr.im/api')
Run Code Online (Sandbox Code Playgroud)
(您可能认为不适合多种原因,如网址的安全性)
>>> import urllib, json
>>> result = urllib.urlopen('https://personal-access-token:x-oauth-basic@api.github.com/repos/:owner/:repo')
>>> r = json.load(result.fp)
>>> result.close()
Run Code Online (Sandbox Code Playgroud)
Mar*_*ski 13
看看这个SO帖子的答案,并从urllib2缺失手册中查看这个基本的身份验证教程.
为了使urllib2基本身份验证起作用,http响应必须包含HTTP代码401 Unauthorized 和一个"WWW-Authenticate"带有值的密钥,"Basic"否则Python将不会发送您的登录信息,您将需要使用请求,或者urllib.urlopen(url)使用您的登录信息. url,或添加@Flowpoke的 答案中的标题.
您可以通过以下方式查看错误urlopen:
try:
urllib2.urlopen(urllib2.Request(url))
except urllib2.HTTPError, e:
print e.headers
print e.headers.has_key('WWW-Authenticate')
Run Code Online (Sandbox Code Playgroud)
推荐的方法是使用requests模块:
#!/usr/bin/env python
import requests # $ python -m pip install requests
####from pip._vendor import requests # bundled with python
url = 'https://httpbin.org/hidden-basic-auth/user/passwd'
user, password = 'user', 'passwd'
r = requests.get(url, auth=(user, password)) # send auth unconditionally
r.raise_for_status() # raise an exception if the authentication fails
Run Code Online (Sandbox Code Playgroud)
这是urllib2基于Python 2/3兼容的单一源代码变体:
#!/usr/bin/env python
import base64
try:
from urllib.request import Request, urlopen
except ImportError: # Python 2
from urllib2 import Request, urlopen
credentials = '{user}:{password}'.format(**vars()).encode()
urlopen(Request(url, headers={'Authorization': # send auth unconditionally
b'Basic ' + base64.b64encode(credentials)})).close()
Run Code Online (Sandbox Code Playgroud)
Python 3.5+介绍HTTPPasswordMgrWithPriorAuth()允许:
..以消除不必要的401响应处理,或无条件地在第一个请求上发送凭据,以便与未返回404响应的服务器进行通信,如果未发送Authorization标头,则返回401.
#!/usr/bin/env python3
import urllib.request as urllib2
password_manager = urllib2.HTTPPasswordMgrWithPriorAuth()
password_manager.add_password(None, url, user, password,
is_authenticated=True) # to handle 404 variant
auth_manager = urllib2.HTTPBasicAuthHandler(password_manager)
opener = urllib2.build_opener(auth_manager)
opener.open(url).close()
Run Code Online (Sandbox Code Playgroud)
这是很容易更换HTTPBasicAuthHandler()有ProxyBasicAuthHandler()必要时在这种情况下.